Giới thiệu
Trong lập trình JavaScript, việc xử lý bất đồng bộ là một phần không thể thiếu. Với sự ra đời của các từ khóa async và await, việc viết mã bất đồng bộ trở nên dễ dàng và trực quan hơn. Bài viết này sẽ giúp bạn hiểu rõ về cách sử dụng async và await, cùng với những ví dụ thực tế và các mẹo tối ưu hóa hiệu suất.
Từ Khóa async Là Gì?
Từ khóa async được sử dụng trước một hàm để đảm bảo rằng hàm đó luôn trả về một Promise. Điều này có nghĩa là bất kỳ giá trị nào được trả về từ hàm async sẽ tự động được bọc trong một Promise.
Ví dụ:
javascript
async function greet() {
return "Xin chào!";
}
greet().then(msg => console.log(msg)); // Kết quả: Xin chào!
Từ Khóa await Là Gì?
Từ khóa await được sử dụng để tạm dừng việc thực thi của một hàm async cho đến khi một Promise được giải quyết. Điều này giúp chúng ta dễ dàng xử lý các thao tác bất đồng bộ mà không cần phải sử dụng các chuỗi .then() phức tạp.
Ví dụ:
javascript
async function fetchData() {
let promise = new Promise((resolve) => {
setTimeout(() => resolve("Dữ liệu đã nhận!"), 2000);
});
let result = await promise;
console.log(result); // Kết quả sau 2 giây: Dữ liệu đã nhận!
}
fetchedData();
Cách async và await Hoạt Động Cùng Nhau
Sự kết hợp giữa async và await giúp mã bất đồng bộ trông giống như mã đồng bộ, làm cho việc đọc và bảo trì mã trở nên dễ dàng hơn. Dưới đây là một so sánh giữa việc sử dụng .then() và async/await:
So Sánh:
| Cách sử dụng | Với .then() |
Với async/await |
|---|---|---|
| Đọc mã | Khó hơn do nhiều cấp độ lồng ghép | Dễ đọc hơn, giống như mã đồng bộ |
| Xử lý lỗi | Sử dụng .catch() |
Sử dụng try...catch |
Ví dụ với .then():
javascript
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log("Lỗi:", error));
Ví dụ với async/await:
javascript
async function getData() {
try {
let res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
let data = await res.json();
console.log(data);
} catch (error) {
console.log("Lỗi:", error);
}
}
getData();
Xử Lý Lỗi Với try...catch
Khi làm việc với các Promise, việc xử lý lỗi là rất quan trọng. Sử dụng cấu trúc try...catch trong hàm async giúp chúng ta dễ dàng phát hiện và xử lý lỗi.
Ví dụ:
javascript
async function getData() {
try {
let res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
let data = await res.json();
console.log(data);
} catch (error) {
console.log("Lỗi:", error);
}
}
getData();
Khi Nào Nên Sử Dụng async/await
- Khi làm việc với các cuộc gọi API (sử dụng
fetch,Axios). - Khi bạn muốn mã sạch hơn thay vì phải sử dụng chuỗi
.then()phức tạp. - Khi việc xử lý lỗi là rất quan trọng để giảm thiểu sự cố.
Các Thực Hành Tốt Nhất Khi Sử Dụng async/await
- Sử dụng
try...catch: Luôn luôn bao bọc mã của bạn trong một khốitry...catchđể xử lý các lỗi bất ngờ. - Giữ cho mã ngắn gọn: Tránh lồng ghép quá nhiều
awaittrong cùng một hàm có thể làm giảm hiệu suất. - Sử dụng
Promise.all: Nếu bạn cần thực hiện nhiều Promise song song, hãy sử dụngPromise.all()để tăng tốc độ thực thi.
Ví dụ với Promise.all:
javascript
async function fetchMultipleData() {
try {
const [data1, data2] = await Promise.all([
fetch("https://jsonplaceholder.typicode.com/posts/1"),
fetch("https://jsonplaceholder.typicode.com/posts/2")
]);
const result1 = await data1.json();
const result2 = await data2.json();
console.log(result1, result2);
} catch (error) {
console.log("Lỗi:", error);
}
}
fetchMultipleData();
Những Cạm Bẫy Thường Gặp
- Quên từ khóa
async: Nếu bạn quên thêm từ khóaasync, hàm sẽ trả về một giá trị thay vì Promise. - Xử lý lỗi không đầy đủ: Đảm bảo rằng bạn đã xử lý tất cả các lỗi có thể xảy ra.
Mẹo Tối Ưu Hóa Hiệu Suất
- Giảm thiểu số lượng await: Sử dụng
Promise.all()khi có thể để giảm thiểu thời gian chờ. - Chỉ sử dụng await khi cần thiết: Tránh việc sử dụng
awaitnếu không cần thiết để giữ cho mã nhanh và hiệu quả.
Kết Luận
Việc sử dụng async và await giúp cho lập trình viên JavaScript có thể viết mã bất đồng bộ một cách dễ dàng và hiệu quả hơn. Hãy áp dụng những gì bạn đã học trong bài viết này vào dự án của mình để cải thiện hiệu suất và khả năng bảo trì mã.
Câu Hỏi Thường Gặp
1. async và await có thể được sử dụng trong các hàm không?
Có, bạn chỉ cần thêm từ khóa async trước hàm và sử dụng await bên trong.
2. Có thể sử dụng await bên ngoài một hàm async không?
Không, await chỉ có thể được sử dụng bên trong hàm có từ khóa async.
3. Có nên sử dụng async/await cho tất cả các cuộc gọi API không?
Nên, vì nó giúp mã bạn trở nên sạch sẽ và dễ bảo trì hơn.