Cái này trong javascript toidicodedao

Lâu rồi chưa viết bài về kỹ thuật nên hôm nay viết bài để dân tình biết là mình vẫn còn code nhé

Kỳ này, chúng ta sẽ tìm hiểu về async/await, một cặp từ khóa rất bá đạo trong JavaScript chuẩn ES2017. Biết cách sử dụng async/await sẽ giúp ta viết code ngắn gọn, hiệu quả và dễ dàng hơn rất nhiều nhé

Retented architecture

JavaScript is the single-thread language, tức là chỉ có một luồng duy nhất để thực thi các dòng lệnh. Nếu chạy theo cơ chế đồng bộ [đồng bộ] thì khi thực hiện phức tạp tính toán, gọi yêu cầu AJAX tới máy chủ, gọi cơ sở dữ liệu [trong NodeJS], luồng này sẽ dừng để chờ, làm toàn bộ trình duyệt bị… treo

Để tránh điều này, hầu hết mã gọi yêu cầu AJAX hoặc cơ sở dữ liệu trong JavaScript đều chạy theo cơ chế bất đồng bộ [không đồng bộ]. Ban đầu, việc chạy mã không đồng bộ trong JavaScript được thực hiện nhờ gọi lại [như đoạn mã bên dưới]


Tệp này chứa văn bản Unicode hai chiều có thể được diễn giải hoặc biên dịch khác với nội dung hiển thị bên dưới. Để xem lại, hãy mở tệp trong trình chỉnh sửa hiển thị các ký tự Unicode bị ẩn.
Tìm hiểu thêm về ký tự Unicode hai chiều

Hiển thị ký tự ẩn





// Truyền gọi lại vào hàm ajaxvar gọi lại = function[image]{console.log[hình ảnh]; . };ajax.nhận["gaixinh. info", gọi lại];// Có thể viết gọn như sauajax.nhận["gaixinh. thông tin", chức năng[hình ảnh] {console.log[hình ảnh];}]

xem thô

ajax_callback. js

được lưu trữ với ❤ ​​bởi GitHub

Tất nhiên, vì callback có một số nhược điểm như code long line, callback hell,… nên người ta tạo ra 1 pattern mới call là Promise

Các bạn nên xem lại kiến ​​thức về Callback trong JavaScript và Promise trong JavaScript để có thể nắm rõ kiến ​​thức phía dưới bài viết này nhé

Từ gọi lại, hứa đến Async/Await

Hứa sẽ giải quyết tốt các vấn đề của cuộc gọi lại. Mã trở nên dễ đọc, tách biệt và dễ bắt lỗi hơn

Mã trở nên gọn đẹp khi chuyển từ gọi lại qua lời hứa

Tuy nhiên, dùng promise kép khi ta vẫn thấy hơi khó chịu vì phải truyền callback vào hàm then và catch. Code cũng sẽ hơi thừa và khó debug, vì toàn bộ hàm thì chỉ được tính là 1 câu lệnh nên không debug từng dòng được

May thay, in ES7 a allow color mang tên async/await đã ra đời. [Mình nghi 99% là phép màu này ăn cắp từ C# hay ho, vì C# đã có async/await từ thời của ông địa trường rồi cơ]

Xem đối tượng Promise như thể chúng là đối tượng đồng bộ

Vì vậy async/await có gì hay ho? .  

Như ở phía trên, hàm findRandomImgPromise là hàm bất đồng bộ, trả về một Promise. Với từ khóa đang chờ, ta có thể coi hàm này là đồng bộ, câu lệnh phía sau chỉ được chạy sau khi hàm này trả về kết quả

Bấm Run Pen để xem demo nhé

Tại sao nên sử dụng async/await?

Như mình đã nói, async/await có một số điểm vượt trội so với lời hứa

  • Code dễ đọc hơn rất rất nhiều, không cần thiết rồi bắt gì cả, cứ viết như code chạy tuần tự, sau đó dùng try/catch thông thường để bắt lỗi
  • Viết vòng lặp qua từng phần tử trở nên vô cùng đơn giản, chỉ công việc chờ đợi trong mỗi vòng lặp
  • Gỡ lỗi dễ dàng hơn nhiều, vì mỗi lần sử dụng await được tính là một dòng mã, do đó ta có thể đặt trình gỡ lỗi để gỡ lỗi từng dòng như bình thường
  • Khi có lỗi, ngoại lệ sẽ chỉ ra lỗi ở dòng số nhiều chứ không phải chung chung là lời hứa chưa được giải quyết
  • With promise or callback, việc kết hợp if/else hoặc retry với code không đồng bộ là cực hình vì ta phải viết code lòng vòng, rắc rối. Với async/await, công việc này vô cùng dễ dàng
Async/Await làm code trở nên gọn gàng sạch đẹp như thế nào

Một vòng lặp demo khá thú vị bằng async đang chờ

Unupdate of async/await

Tất nhiên, async/await cũng có một số bất cập mà các bạn cần lưu ý khi sử dụng

  • Cannot run on old browser. Nếu dự án yêu cầu phải chạy trên các trình duyệt cũ, bạn sẽ phải sử dụng Babel để transpiler code ra ES5 để chạy
  • Khi chúng ta chờ đợi một lời hứa bị từ chối, JavaScript sẽ đưa ra một ngoại lệ. Do đó, nếu dùng async đang chờ mà quên try catch thì lâu lâu chúng ta sẽ bị… lỗi hoặc code tiếp tục chạy
  • không đồng bộ và chờ đợi bắt buộc phải đi kèm với nhau. await only used in async function, if not will be syntax error. Do đó, async/await sẽ dần dần phát triển toàn bộ các hàm trong mã của bạn
async/await is not run on IE, Microsoft Edge 14 và một số trình duyệt cũ hơn

Áp dụng async/await vào mã

Về bản chất, một hàm async sẽ trả về một lời hứa, tương ứng với Tác vụ trong C#. Làm như vậy, để có thể sử dụng async/await một cách hiệu quả, các bạn phải xác định rõ cơ chế làm việc của Promise nhé

Hiện tại phiên bản mới nhất của Chrome, Edge và Firefox đã hỗ trợ async/await, nếu dự án không bắt hỗ trợ các trình duyệt cũ, các bạn cứ thoải mái sử dụng async/await để code gọn đẹp hơn nhé.

Ngoài ra, nếu bạn sử dụng NodeJS, có thể sử dụng combo Promisify + Async/Await như sau

  1. Use Bluebird or util. promisify [Node 8 trở lên] để biến hàm callback của NodeJS thành Promise
  2. Use async/await to get results from this Promise

Kết quả

Bài viết kỳ này hơi phức tạp, lại cần nhiều kiến ​​thức nền về JavaScript nên sẽ hơi khó hiểu

Các bạn cố gắng đọc lại 2,3 lần, xem lại các mẫu mã để hiểu nha. Nếu có thắc mắc hay có gì cần chia sẻ, các bạn cứ thoải mái comment nhé!

Chủ Đề