Giới thiệu về Promise trong JavaScript
Bạn đã biết rằng việc sử dụng mô hình bất đồng bộ dựa trên callback dễ dẫn đến tình huống callback hell. Do đó, trong JavaScript đã giới thiệu một mô hình mới gọi là promise (promise). Hãy cùng tìm hiểu mô hình này.
Một promise là một đối tượng, được truyền vào một hàm làm tham số, bên trong hàm đó cần đặt mã bất đồng bộ của chúng ta:
let promise = new Promise(function() {
// mã bất đồng bộ
});
Như bạn thấy, tôi đã ghi đối tượng promise
vào biến promise. Ở một nơi khác trong mã,
tôi có thể áp dụng cho biến này phương thức
then, truyền vào đó một hàm
với mã cần được thực thi khi
mã bất đồng bộ, được viết khi tạo promise này, hoàn thành:
promise.then(function() {
// sẽ thực thi khi mã bất đồng bộ hoàn thành
});
Nghe có vẻ rối rắm, vì vậy hãy xem một ví dụ. Giả sử tôi có mã bất đồng bộ như thế này:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Giả sử tôi muốn giải quyết cho nó nhiệm vụ chính
của tính bất đồng bộ: thực thi một đoạn mã nào đó sau khi bộ đếm thời gian kích hoạt. Đồng thời
tôi không muốn đặt mã đó trong chính bộ đếm thời gian
và muốn kết quả,
mà tôi đã viết trong biến result, bằng cách nào đó sẽ được truyền vào mã đó.
Nói chung, chúng ta đã giải quyết nhiệm vụ này trong các bài học trước
thông qua callback và đăng ký. Bây giờ hãy
xem cách thực hiện điều đó thông qua promise.
Đầu tiên cần bọc mã bất đồng bộ của chúng ta trong một promise:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Tuy nhiên, điều này là chưa đủ. Chúng ta phải chỉ định một cách rõ ràng rằng mã bất đồng bộ của chúng ta đã hoàn thành. Một hàm hoàn thành đặc biệt sẽ giúp chúng ta trong việc này, hàm này tự động được truyền vào tham số đầu tiên của hàm, nếu nó được chỉ định:
let promise = new Promise(function(resolve) { // chỉ định tham số
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Với hàm hoàn thành, chúng ta có thể rõ ràng chỉ định cho promise rằng mã bất đồng bộ đã hoàn thành. Để làm điều này, chúng ta phải gọi hàm này ở nơi chúng ta cần:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // hoàn thành promise
}, 3000);
});
Đồng thời, nếu chúng ta muốn truyền ra bên ngoài một kết quả nào đó của mã bất đồng bộ, chúng ta có thể truyền nó làm tham số cho hàm hoàn thành của chúng ta:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // truyền kết quả
}, 3000);
});
Tất nhiên, có thể loại bỏ biến trung gian:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Bây giờ ở bất kỳ nơi nào khác, chúng ta có thể gọi
phương thức then của promise của chúng ta:
promise.then(function() {
// sẽ kích hoạt khi promise hoàn thành
});
Kết quả thực thi của promise sẽ được truyền vào tham số đầu tiên của hàm, nếu chúng ta muốn chỉ định nó:
promise.then(function(result) {
console.log(result); // sẽ in mảng kết quả
});
Tạo một promise, bên trong promise đó có một độ trễ
5 giây, sau đó promise sẽ
hoàn thành, trả về một văn bản nào đó làm kết quả của nó.
In văn bản đó ra màn hình.