Series JavaScript sida – Promise – Hứa thật nhiều thất hứa thật nhiều

Bài viết này sẽ giới thiệu về khái niệm promise và các ứng dụng của nó trong javascript. Promise được sử dụng khá nhiều ở cả front-end (AngularJS) và back-end(NodeJS), do đó nắm vững khái niệm này sẽ giúp bạn rất nhiều trong việc code và … trả lời phỏng vấn.

Lưu ý: Bài viết sử dụng nhiều ngôn ngữ 16+, khuyến phụ nữ dưới 18 tuổi và trẻ em có thai không nên đọc.

Lập trình bất đồng bộ trong Javascript

Bạn nào từng làm AJAX đều biết rằng Javascript kết nối với server theo cơ chế bất đồng bộ, các hàm phía sau không đợi hàm AJAX chạy xong mà tiếp tục chạy luôn.

Do đó, để lấy kết quả của hàm ajax, ta phải truyền cho nó 1 callback. Sau khi hàm AJAX lấy được kết quả, nó sẽ gọi hàm callback với kết quả thu được.

Cách làm này có gì không ổn? Sử dụng callback chồng chéo sẽ làm code trở nên rối rắm, khó đọc; việc bắt exception, hiển thị lỗi trở cũng nên phức tạp.

Để giải quyết vấn đề này, các bác developer đã sáng tạo ra một khái niệm gọi là promise.

Promise là chi? Promise là… lời hứa!

Khái niệm promise được MDN giải thích một cách khá mù mờ và hơi… khó hiểu:

The Promise object is used for asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.

JSPromise

Để dễ hiểu, mình gọi Promise là lời hứa. Tương tự như trong thực tế, có người hứa rồi làm, có người hứa rồi … thất hứa.

Một lời hứa có 3 trạng thái sau:

  • pending: Hiện lời hứa chỉ là lời hứa suông, còn đang chờ người khác thực hiện
  • fulfilled: Lời hứa đã được thực hiện
  • reject: Bạn đã bị thất hứa, hay còn gọi là bị “xù”

Khi xưa, để dụ bạn cố gắng học hành, bố mẹ bảo “Ráng đậu đại học bố mẹ sẽ mua cho con BMW đi học cho bằng bạn bằng bè”. Lúc này, thứ bạn nhận được là một lời hứa, chứ không phải xe BMW.

Khi lời hứa được thực hiện, promise sẽ gọi callback trong hàm then. Ngược lại, khi bị thất hứa, promise sẽ gọi callback trong hàm catch.

Quay lại với ví dụ ở đầu bài. Lúc này hàm ajax sẽ trả ra một lời hứa. Hàm này hứa là “Nếu lấy ảnh XXX, ta sẽ đưa cho mày”. Lúc này kết quả của hàm là một promise, chứ không phải là ảnh XXX.

Ủa, cũng là dùng callback thôi mà??

Ừ, hồi mới tìm hiểu về promise mình cũng nghĩ tương tự như các bạn vậy đó. Vậy thì promise có gì hay mà phải dùng?

Promise hay ở các điểm sau:

  1. Promise hỗ trợ “chaining”
  2. Promise giúp bắt lỗi dễ dàng hơn
  3. Xử lý bất đồng bộ

Cùng phân tích các điểm hay của Promise nhé.

1. Promise chaining

Giá trị trả về của hàm then là 1 promise khác. Do vậy ta có thể dùng promise gọi liên tiếp các hàm bất đồng bộ. Có thể viết lại hàm phía trên như sau:

2. Bắt lỗi với promise

Trong ví dụ trên, ta gọi lần lượt 3 hàm: xin_mẹ_mua_xechở_gái_đi_chơichở_gái_vào_hotel.

Chỉ cần một trong 3 hàm này bị lỗi, promise sẽ chuyển qua trạng thái reject. Lúc này callback trong hàm catch sẽ được gọi. Việc bắt lỗi trở nên dễ dàng rất nhiều

3. Xử lý bất đồng bộ

Giả sử bạn muốn 3 hàm AJAX khác nhau. Bạn cần kết quả trả về của 3 hàm này trước khi tiếp tục chạy. Với callback, việc này sẽ khá khó thực hiện. Tuy nhiên, promise hỗ trợ hàm Promise.all, cho phép gộp kết quả của nhiều promise lại với nhau.

Tổng kết

Với các ưu điểm của mình, promise đang dần dần thay thế cho callback. Dĩ nhiên là không thay thế hoàn toàn đâu. Với các hàm đơn giản thì dùng callback sẽ ngắn và dễ hiểu hơn promise.

Promise được sử dụng nhiều trong AngularJS và một số module của NodeJS. Nắm vững khái niệm promise sẽ giúp bạn code đỡ cực hơn nhiều.

Hiện tại, các bạn có thể dùng Promise trong trình duyệt Chrome và các bản NodeJS mới nhất. Với các trình duyệt khác, các bạn phải thêm thư viện promise-polyfill thì mới sử dụng được.

Vì khái niệm promise khá là khó tiêu hóa, mình khuyên các bạn nên đọc lại nhiều lần, kết hợp với xem những bài viết khác liên quan tới nó nhé:

Advertisements

9 thoughts on “Series JavaScript sida – Promise – Hứa thật nhiều thất hứa thật nhiều”

  1. Rất hay, khá dễ hiểu. Nhưng mà ông nên tách code ở mấy đoạn ra làm 2 phần. Ông viết vậy cứ tưởng là xài chung, có đoạn đọc vừa thấy xài call back vừa xài promise =.=, giá như có cái demo trên fiddle thì sẽ rạch ròi hơn nữa. Anyway, this article is helpful !

    Like

  2. Mình thấy đâu cần thiết dùng đến Promise. Ajax cơ bản đã cung cấp cho chúng ta cơ bất đồng bộ hoặc bất đồng bộ rồi. Mặc định là bất đồng bộ, khi khai báo async: false trong hàm ajax hàm script sẽ dừng lại đợi đoạn code ajax chạy xong mới thực hiện tiếp.

    Like

  3. : )) cảm ơn a hoàng, a rảnh có thể viết thêm vài bài về javascript nữa đc ko anh

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s