Promise là một khái niệm quan trọng trong JavaScript, được sử dụng để xử lý các tác vụ bất đồng bộ. Trong một thế giới web ngày càng phát triển, việc quản lý các tác vụ bất đồng bộ một cách hiệu quả trở nên cần thiết. Promise giúp bạn viết mã ngắn gọn, dễ hiểu và dễ bảo trì hơn khi xử lý các tác vụ như gọi API, đọc/ghi tệp, hoặc thao tác với cơ sở dữ liệu.
Khái niệm về Promise
Promise trong JavaScript là một đối tượng đại diện cho một tác vụ bất đồng bộ có thể hoàn thành hoặc thất bại. Promise có ba trạng thái: pending
(đang chờ), fulfilled
(hoàn thành), và rejected
(bị từ chối).
Các trạng thái của Promise
- Pending: Trạng thái ban đầu khi Promise chưa hoàn thành hoặc bị từ chối.
- Fulfilled: Trạng thái khi tác vụ bất đồng bộ hoàn thành thành công.
- Rejected: Trạng thái khi tác vụ bất đồng bộ gặp lỗi hoặc thất bại.
Cách tạo Promise
Bạn có thể tạo một Promise mới bằng cách sử dụng cú pháp new Promise()
, trong đó bạn truyền vào một hàm với hai tham số resolve
và reject
.
let myPromise = new Promise((resolve, reject) => { let success = true; if (success) { resolve("Tác vụ hoàn thành thành công!"); } else { reject("Tác vụ thất bại!"); } });
Sử dụng Promise
Phương thức then()
Phương thức then()
được sử dụng để xử lý kết quả của một Promise sau khi nó hoàn thành.
myPromise.then((message) => { console.log(message); // Kết quả: Tác vụ hoàn thành thành công! });
Phương thức catch()
Phương thức catch()
được sử dụng để xử lý lỗi nếu Promise bị từ chối.
myPromise.catch((error) => { console.log(error); // Kết quả: Tác vụ thất bại! });
Phương thức finally()
Phương thức finally()
được sử dụng để thực hiện hành động sau khi Promise kết thúc, bất kể nó hoàn thành hay bị từ chối.
myPromise.finally(() => { console.log("Tác vụ đã kết thúc."); });
Promise Chaining
Promise chaining cho phép bạn kết hợp nhiều Promise với nhau một cách tuần tự.
myPromise .then((message) => { console.log(message); return new Promise((resolve) => { resolve("Promise tiếp theo hoàn thành!"); }); }) .then((nextMessage) => { console.log(nextMessage); }) .catch((error) => { console.log(error); });
Các phương thức tĩnh của Promise
Promise.all()
Promise.all()
chờ tất cả các Promise hoàn thành trước khi tiếp tục.
let promise1 = Promise.resolve(3); let promise2 = 42; let promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values); // Kết quả: [3, 42, "foo"] });
Promise.race()
Promise.race()
trả về kết quả của Promise đầu tiên hoàn thành, bất kể kết quả đó là thành công hay thất bại.
let promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, "one"); }); let promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, "two"); }); Promise.race([promise1, promise2]).then((value) => { console.log(value); // Kết quả: "two" });
Promise.allSettled()
Promise.allSettled()
chờ tất cả các Promise hoàn thành, không quan trọng là chúng thành công hay thất bại.
let promise1 = Promise.resolve("Success"); let promise2 = Promise.reject("Error"); Promise.allSettled([promise1, promise2]).then((results) => results.forEach((result) => console.log(result.status)) ); // Kết quả: "fulfilled", "rejected"
Promise.any()
Promise.any()
trả về kết quả của Promise đầu tiên được fulfilled
.
let promise1 = Promise.reject("Error"); let promise2 = Promise.resolve("Success"); Promise.any([promise1, promise2]).then((value) => { console.log(value); // Kết quả: "Success" });
Async/Await
Async/await
là cú pháp mới giúp làm việc với Promise trở nên dễ dàng và trực quan hơn.
Giới thiệu về async/await
Async
biến một hàm thành hàm bất đồng bộ và await
tạm dừng thực hiện của hàm cho đến khi Promise hoàn thành.
Ví dụ về async/await
async function fetchData() { try { let response = await fetch("https://api.example.com/data"); let data = await response.json(); console.log(data); } catch (error) { console.log(error); } }
Các lỗi thường gặp và cách khắc phục
Khi làm việc với Promise, bạn có thể gặp một số lỗi phổ biến như quên xử lý lỗi, hoặc không sử dụng return
trong chuỗi Promise.
Các mẹo và lời khuyên để tránh lỗi
- Luôn sử dụng
catch()
để xử lý lỗi. - Sử dụng
return
trong chuỗi Promise để đảm bảo đúng luồng thực thi.
Kết luận
Promise là một phần quan trọng của JavaScript, giúp xử lý các tác vụ bất đồng bộ một cách hiệu quả và dễ quản lý. Hiểu rõ và sử dụng thành thạo Promise sẽ giúp bạn viết mã nguồn JavaScript tối ưu hơn.
Tài nguyên bổ sung
Để tìm hiểu thêm về Promise trong JavaScript, bạn có thể tham khảo các tài liệu sau:
- MDN Web Docs về Promise
- Sách “JavaScript: The Good Parts” của Douglas Crockford
- Khóa học trực tuyến trên freeCodeCamp