Lâu rồi chưa viết bài về kĩ thuật nên hôm nay viết mộ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ừ khoá rất bá đạo trong JavaScript chuẩn ES2017. Biết cách dùng async/await sẽ giúp ta viết code ngắn gọn, hiệu quả và dễ dàng hơn nhiều nhé.
Nhắc lại kiến thức
JavaScript là ngôn ngữ single-thread, tức là chỉ có một thread duy nhất để thực thi các dòng lệnh. Nếu chạy theo cơ chế đồng bộ (synchonous) thì khi thực hiện tính toán phức tạp, gọi AJAX request tới server, gọi database (trong NodeJS), thread 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 code gọi AJAX request hoặc database trong JavaScript đều chạy theo cơ chế bất đồng bộ (asynchnous). Ban đầu, việc chạy code asynchnous trong JavaScript được hiện thực nhờ callback (như đoạn code bên dưới).
Tất nhiên, vì callback có một số nhược điểm như code dài dòng, callback hell,… nên người ta tạo ra 1 pattern mới gọi 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ể hiểu kiến thức phía dưới bài này nhé!
Từ callback, promise đến Async/Await
Promise đã giải quyết khá tốt những vấn đề của callback. Code trở nên dễ đọc, tách biệt và dễ bắt lỗi hơn.
Tuy nhiên, dùng promise đôi 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 dư thừa và khó debug, vì toàn bộ các hàm then chỉ được tính là 1 câu lệnh nên không debug riêng từng dòng được.
May thay, trong ES7 một phép màu 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 ông địa cởi trường rồi cơ).
Vậy async/await có gì hay ho? Chúng giúp chúng ta viết code trông có vẻ đồng bộ (synchonous), nhưng thật ra lại chạy bất đồng bộ (asynchonous).
Như trong hình phía trên, hàm findRandomImgPromise là hàm bất đồng bộ, trả về một Promise. Với từ khoá await, 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ả.