Async/await trong JavaScript

Async/await trong JavaScript

Trong bài viết này, chúng tôi sẽ giải thích về async/await trong JavaScript.

YouTube Video

Async/await trong JavaScript

async (và await) trong JavaScript là các tính năng được thiết kế để giúp việc viết các hoạt động bất đồng bộ trở nên trực quan và dễ đọc hơn. Bằng cách sử dụng điều này, bạn có thể giảm độ phức tạp của các hàm gọi lại (callback) truyền thống và chuỗi Promise, và viết mã bất đồng bộ theo cách giống như mã đồng bộ.

Hàm async

async được sử dụng để định nghĩa một hàm là hàm bất đồng bộ. Một hàm async luôn trả về một Promise. Trong một hàm được đánh dấu bằng async, bạn có thể sử dụng await để đợi kết quả của một Promise được trả về.

Cú pháp cơ bản của một hàm async

1async function myAsyncFunction() {
2    // Write asynchronous processing here
3    return 'Result';  // Return a Promise
4}

Trong trường hợp này, gọi myAsyncFunction() sẽ tự động trả về một đối tượng Promise. Khi Promise được giải quyết, kết quả của nó trở thành giá trị được trả về bởi return.

Ví dụ: Hàm async cơ bản

1async function greet() {
2    return 'Hello, World!';
3}
4
5greet().then((message) => {
6    console.log(message);  // Displays "Hello, World!"
7});

await

await được sử dụng để đợi một Promise được giải quyết. Bằng cách sử dụng await, bạn có thể tạm dừng việc thực thi cho đến khi Promise được giải quyết và nhận kết quả của Promise. await chỉ có thể được sử dụng bên trong một hàm async.

Ví dụ: Cách sử dụng await

 1async function fetchData() {
 2    // Wait for the result of the Promise
 3    const data = await fetch('https://codesparklab.com/json/example.json');
 4    // Wait for the asynchronous operation to complete
 5    const jsonData = await data.json();
 6    // Retrieve and display the data
 7    console.log(jsonData);
 8}
 9
10fetchData();

Trong ví dụ trên, nó chờ Promise được trả về bởi hàm fetch bằng await, và sau đó thực hiện các hoạt động bất đồng bộ khác bằng cách sử dụng kết quả.

Xử lý lỗi với async/await

Nếu một lỗi xảy ra bên trong hàm async, lỗi đó sẽ được coi như là một reject của Promise. Bạn có thể sử dụng câu lệnh try...catch để thực hiện xử lý lỗi.

Ví dụ: Xử lý lỗi

 1async function fetchData() {
 2    try {
 3        // Invalid URL
 4        const data = await fetch('https://api.invalid-url.com/data');
 5        const jsonData = await data.json();
 6        console.log(jsonData);
 7    } catch (error) {
 8        // Catch the error
 9        console.error('Failed to fetch data:', error);
10    }
11}
12
13fetchData();

Sử dụng một khối try...catch cho phép bạn bắt lỗi xảy ra trong quá trình thực hiện các hoạt động bất đồng bộ, ngăn chương trình bị sập khi xảy ra lỗi.

Lợi ích của async/await

So với chuỗi Promise truyền thống, async/await mang lại những ưu điểm sau:.

  • Cải thiện khả năng đọc mã
    • Xử lý bất đồng bộ có thể được viết giống như mã đồng bộ, tránh được sự phức tạp của các chuỗi Promise lồng nhau sâu và các hàm callback.
  • Dễ dàng gỡ lỗi hơn
    • Vì nó giống với mã đồng bộ, việc gỡ lỗi và xử lý lỗi trở nên dễ dàng hơn.
  • Bảo trì tốt hơn
    • Các quá trình bất đồng bộ có thể được viết đơn giản hơn, giúp dễ dàng thay đổi hoặc chỉnh sửa mã và nâng cao khả năng bảo trì lâu dài.

Ví dụ: chuỗi Promise so với async/await

Hãy so sánh mã sử dụng chuỗi Promise với mã sử dụng async/await.

 1// Code using Promise chains
 2function fetchDataPromise() {
 3    fetch('https://codesparklab.com/json/example.json')
 4        .then((response) => response.json())
 5        .then((data) => {
 6            console.log(data);
 7        })
 8    .catch((error) => {
 9        console.error('Failed to fetch data:', error);
10    });
11}
12
13// Code using async/await
14async function fetchDataAsync() {
15    try {
16        const response = await fetch('https://codesparklab.com/json/example.json');
17        const data = await response.json();
18        console.log(data);
19    } catch (error) {
20        console.error('Failed to fetch data:', error);
21    }
22}

Như bạn có thể thấy, sử dụng async/await cho phép bạn viết các quá trình bất đồng bộ theo cách tuyến tính, dẫn đến mã dễ đọc hơn.

Thực hiện nhiều hoạt động bất đồng bộ cùng lúc

Bằng cách kết hợp Promise.all() hoặc Promise.race() với await, bạn có thể thực hiện nhiều hoạt động bất đồng bộ cùng lúc và xử lý kết quả của chúng tổng hợp.

Ví dụ: Thực hiện nhiều hoạt động bất đồng bộ đồng thời

 1async function fetchMultipleData() {
 2    try {
 3        const [data1, data2] = await Promise.all([
 4            fetch('https://codesparklab.com/json/example1.json'),
 5            fetch('https://codesparklab.com/json/example2.json')
 6        ]);
 7        const jsonData1 = await data1.json();
 8        const jsonData2 = await data2.json();
 9        console.log(jsonData1, jsonData2);
10    } catch (error) {
11        console.error('Failed to fetch data:', error);
12    }
13}
14
15fetchMultipleData();

Promise.all() giải quyết nhiều Promise cùng lúc và trả về kết quả của chúng dưới dạng một mảng. Nó chờ tất cả Promise được giải quyết, và nếu bất kỳ Promise nào thất bại, toàn bộ sẽ được xem như thất bại.

Tóm tắt

  • Hàm async: Luôn trả về một Promise và được sử dụng để viết xử lý bất đồng bộ.
  • await: Được sử dụng để chờ một Promise được giải quyết và nhận kết quả của nó.
  • Xử lý lỗi: Sử dụng try...catch để xử lý các lỗi xảy ra trong quá trình xử lý bất đồng bộ.
  • Nhiều hoạt động bất đồng bộ: Bạn có thể thực hiện nhiều hoạt động bất đồng bộ cùng lúc bằng Promise.all().

async/await là các công cụ mạnh mẽ để xử lý bất đồng bộ, vì vậy hãy chắc chắn tận dụng chúng để đơn giản hóa logic bất đồng bộ phức tạp.

Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.

YouTube Video