Tìm hiểu Promise trong 5 phút
Bài đăng này đã không được cập nhật trong 6 năm
1. Nội dung
Bài viết này sẽ giới thiệu cho bạn những điều cơ bản về Promise
trong JavaScript. Đây không phải là một bài viết bao gồm tất cả, nhưng thay vào đó sẽ cung cấp cho bạn kiến thức cơ bản mà bạn cần phải hiểu và bắt đầu sử dụng Promise
trong source code của bạn.
2. Tại sao chúng ta cần Promise
Promise
(giống như callbacks) cho phép chúng ta chờ đợi một đoạn code
phải hoàn thành, trước khi chạy đoạn code
tiếp theo.
Tại sao nó lại quan trọng ư? Bạn hãy tưởng tượng về một trang web tải dữ liệu từ một API, sau đó xử lý và định dạng dữ liệu để hiển thị cho người dùng. Nếu chúng ta thực hiện xử lý và định dạng dữ liệu trước khi API tìm nạp thông tin, chúng ta chắc chắn sẽ gặp lỗi hoặc sẽ thành một trang web trống. Bằng cách sử dụng Promise
, chúng ta có thể đảm bảo rằng dữ liệu API không được xử lý / định dạng cho đến khi việc gọi API đã thành công.
3. Promise
là gì?
Trong JavaScript, Promise
thể hiện kết quả cuối cùng của một tiến trình không đồng bộ. Hãy nghĩ về nó như một placeholder
. Placeholder
này về bản chất là một đối tượng mà trên đó chúng ta có thể đính kèm các callback
.
Promise
có thể có một trong ba trạng thái:
Pending - Thao tác không đồng bộ chưa hoàn thành
Fulfilled - Hoạt động đã hoàn thành và Promise
có giá trị
Rejected - Thao tác đã hoàn thành với lỗi hoặc không thành công.
Promise
sẽ được giải quyết nếu nó không ở trạng thái pending
. Khi Promise
đã ổn định, nó được giải quyết tốt. Nó không thể chuyển sang bất kỳ trạng thái nào khác
4. Làm việc với Promise
Hầu hết thời gian khi làm việc với Promises
, bạn sẽ sử dụng những Promise
đã được tạo ra và được trả về từ các hàm. Tuy nhiên, bạn cũng có thể tạo Promise
với hàm tạo của nó.
Dưới đây là Promise
đơn giản giống như này:
runFunction().then(successFunc, failureFunc);
Với ví dụ trên, trước tiên chúng ta gọi hàm runFunction()
. Vì hàm runFunction()
trả về một Promise
, chỉ khi Promise
hoàn thành, hàm successFunc
hoặc hàm failFunc
của mới có thể chạy. Nếu Promise
được thực hiện, hàm sucessFunc
được gọi. Nếu Promise
thất bại, hàm failureFunc
được gọi.
5. Ví dụ về Promise
Bây giờ chúng ta hãy thử tạo mới một Promise
xem nhé:
function delay(t){
return new Promise(function(resolve){
return setTimeout(resolve, t)
});
}
function logHi(){
console.log('hi');
}
delay(2000).then(logHi);
Ở ví dụ trên chúng ta có hai function - delay()
và logHi()
. Hàm logHi()
in ra 'hi'
trên giao diện console ở trình duyệt. Hàm delay()
phức tạp hơn một chút. Nó trả về một Promise
để thực hiện một khung thời gian t
được cung cấp.
Chúng ta sử dụng phương thức then()
để đăng ký callback
để Promise
nhận được giá trị fulfilled
hoặc rejected
.
Chúng ta có thể sử dụng delay(2000).then(logHi)
để đặt thời gian trong 2000 mili giây (2 giây) vào cho việc delay của ví dụ trên. Sau 2 giây đã trôi qua, Promise
sẽ được thực hiện, và chỉ khi đó hàm logHi
mới được gọi.
6. Chaining Promises
Một trong những lợi ích chính của Promises
là chúng cho phép chúng ta kết nối các hoạt động không đồng bộ với nhau. Điều này có nghĩa là chúng ta có thể chỉ định các hoạt động tiếp theo để bắt đầu chỉ khi hoạt động trước đó đã thành công. Đây được gọi là Chaining Promises
. Dưới đây là một ví dụ:
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 2000);
}).then((result) => {
alert(result);
return result + 2;
}).then((result) => {
alert(result);
return result + 2;
}).then((result) => {
alert(result);
return result + 2;
});
(Bạn có thể paste vào console của trình duyệt để test thử.)
Ở trên, Promise
ban đầu sẽ giải quyết trong 2000 mili giây với giá trị là 1. Sau khi giải quyết, trình xử lý then()
được gọi và giá trị 1 được in lên màn hình console. Cuối cùng, giá trị được thêm vào 2 và giá trị 3 được trả về. Giá trị này được chuyển cho trình xử lý tiếp theo sau đó () và quá trình lặp lại.
Rõ ràng đây không phải là một ví dụ trong các dự án thực, nhưng nó sẽ minh họa cho bạn cách mà Promise
có thể được kết nối với nhau. Điều này rất hữu ích với một số tác vụ nhất định trong JavaScript
như tải tài nguyên bên ngoài hoặc chờ dữ liệu API trước khi xử lý.
7. Error Handling
Cho đến thời điểm này, chúng ta mới chỉ thao tác với các Promise
có thể xử lý. Ngoài ra, chúng ta có thể sử dụng .catch ()
để bắt tất cả các lỗi trong Promise chaining
.
Hãy thử xem xét một ví dụ nhé:
// ....
})
.catch((e) => {
console.log('error: ', e)
}
Ví dụ trên là một cách sử dụng .catch()
đơn giản để nhận được thông báo lỗi và trả về trên màn hình console.
Bây giờ chúng ta hãy thêm phần xử lý lỗi .catch()
vào ví dụ trên:
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 2000);
}).then((result) => {
alert(result);
return result + 2;
}).then((result) => {
throw new Error('FAILED HERE');
alert(result);
return result + 2;
}).then((result) => {
alert(result);
return result + 2;
}).catch((e) => {
console.log('error: ', e)
});
Ví dụ trên chỉ có 2 sự thay đổi, đó là sau .then()
thứ hai, chúng ta đã thêm một lỗi Error('FAILED HERE');
và phần bắt lỗi .catch()
ở cuối chuỗi.
Những gì đã xảy ra là:
Promise chạy sau 2 giây với giá trị là 1. Giá trị này pass .then()
đầu tiên và được alert trên màn hình. Tiếp theo nó gặp .then()
thứ 2 và một lỗi được tạo mới. Việc thực thi được dừng lại ngay lập tức và Promise
chuyển đến trạng thái rejected
. .catch()
nhận giá trị lỗi và in vào console của trình duyệt.
Kết quả sẽ như hình:
8. Kết luận
Hi vọng bài viết giúp bạn có cái nhìn khách quan về Promise
trong javascript
Cảm ơn đã theo dõi (bow)
Tài liệu tham khảo: https://codeburst.io/javascript-learn-promises-f1eaa00c5461
All rights reserved