4.1 Từ khóa async
Hàm bất đồng bộ trong JavaScript cho phép viết mã bất đồng bộ mà nhìn và đọc như mã đồng bộ.
Từ khóa async
và await
, được giới thiệu trong ECMAScript 2017 (ES8), giúp làm việc với promises
dễ dàng hơn và làm cho mã dễ hiểu và quản lý hơn.
Những khái niệm chính
Từ khóa async
trước khai báo hàm chỉ ra rằng hàm là bất đồng bộ. Hàm bất đồng bộ luôn trả về promise, thậm chí nếu trong đó không rõ ràng sử dụng toán tử return
.
Nếu hàm trả về giá trị, nó tự động được gói trong một promise với giá trị đó.
Cú pháp:
async function tên() {
// mã hàm
}
Ví dụ:
async function greet() {
return 'Hello, world!';
}
greet().then((message) => {
console.log(message); // Sẽ in ra: Hello, world!
});
4.2 Từ khóa await
Từ khóa await
được sử dụng bên trong hàm bất đồng bộ để tạm dừng thực thi cho đến khi promise
hoàn thành. await
chỉ có thể được sử dụng bên trong các hàm được khai báo với từ khóa async
.
Cú pháp:
let result = await
promise;
Ví dụ:
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function greet() {
await delay(2000);
return 'Hello, world!';
}
async function displayGreeting() {
const message = await greet();
console.log(message); // Sẽ in ra: Hello, world! sau 2 giây
}
displayGreeting();
4.3 Các ví dụ sử dụng async và await
Ví dụ 1: Hàm bất đồng bộ với chờ đợi nhiều promises
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const data1 = await fetchData1();
console.log(data1); // Sẽ in ra: Data 1 sau 1 giây
const data2 = await fetchData2();
console.log(data2); // Sẽ in ra: Data 2 sau 2 giây
}
fetchAllData();
Ví dụ 2: Thực hiện song song các thao tác bất đồng bộ
Để thực hiện nhiều thao tác bất đồng bộ song song, có thể sử dụng Promise.all()
với await
.
function fetchData1() {
return new Promise((resolve) => setTimeout(() => resolve('Data 1'), 1000));
}
function fetchData2() {
return new Promise((resolve) => setTimeout(() => resolve('Data 2'), 2000));
}
async function fetchAllData() {
const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
console.log(data1); // Sẽ in ra: Data 1 sau 2 giây
console.log(data2); // Sẽ in ra: Data 2 sau 2 giây
}
fetchAllData();
Ví dụ 3: Xử lý lỗi với try...catch
Hàm bất đồng bộ cho phép sử dụng khối try...catch
để xử lý lỗi, làm cho mã dễ đọc và quản lý hơn.
function fetchDataWithError() {
return new Promise((resolve, reject) => setTimeout(() => reject('Error occurred'), 1000));
}
async function fetchData() {
try {
const data = await fetchDataWithError();
console.log(data);
} catch (error) {
console.error('Error:', error); // Sẽ in ra: Error: Error occurred sau 1 giây
}
}
fetchData();
Ví dụ 4: Sử dụng async và await trong phương thức lớp
Hàm bất đồng bộ có thể sử dụng trong phương thức lớp.
class DataFetcher {
async fetchData() {
const data = await new Promise((resolve) => setTimeout(() => resolve('Fetched Data'), 1000));
return data;
}
}
const fetcher = new DataFetcher();
fetcher.fetchData().then((data) => {
console.log(data); // Sẽ in ra: Fetched Data sau 1 giây
});
Ví dụ 5: Bộ lặp bất đồng bộ
Bộ lặp bất đồng bộ cho phép làm việc với luồng dữ liệu đến bất đồng bộ.
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
await new Promise((resolve) => setTimeout(resolve, 1000));
yield i++;
}
}
async function iterateAsyncGenerator() {
for await (let value of asyncGenerator()) {
console.log(value); // Sẽ in ra 0, 1 và 2 với khoảng cách 1 giây
}
}
iterateAsyncGenerator();
GO TO FULL VERSION