Danh sách bài học
Promise là gì?
Dẫn nhập
Trong bài viết hôm nay, Kteam sẽ giới thiệu cho các bạn một tính năng mới của Javascript ES6: Promise.
Nội dung
Để theo dõi bài này tốt nhất, bạn nên xem qua bài:
- Sổ tay Javascript
- ECMAScript là gì?
- Node.js là gì?
- Cơ chế bất đồng bộ trong Javascript
- Node.js hoạt động như thế nào?
Bài này sẽ giới thiệu những nội dung sau:
- Promise là gì?
- Cơ chế hoạt động của Promise
- Tại sao phải sử dụng Promise?
- Promise chaining
Promise là gì?
Promise object đại diện cho việc hoàn thành kết quả (hoặc sự thất bại) từ một lệnh bất đồng bộ, và giá trị kết quả của lệnh đó.
Mục đích của Promise là cơ chế của nó giúp bạn thực hiện các tác vụ đồng bộ hơn và tránh rơi vào tình trạng callback hell hay pyramid of doom, là tình trạng dùng các callback lồng nhau quá nhiều
Ta sẽ tạo promise object thông qua class Promise, class Promise lúc khởi tạo sẽ chứa 1 function để thực thi các tác vụ bất đồng bộ. Function sẽ có 2 tham số:
- resolve: hàm được gọi khi promise hoàn thành
- reject: hàm được gọi khi có sự cố
Ví dụ:
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 1000);
});
promise.then(function(value) {
console.log(value);
});
console.log(promise);
- Ta sẽ tạo ra một promise object; tại function bên trong, ta hẹn sau 1 giây sẽ gọi function resolve với kết quả ‘foo’
- Để xử lý khi promise có kết quả ta sẽ dùng phương thức then, rồi viết callback trong đó log ra value khi mà có kết quả
Ta sẽ xem kết quả của nó:
Cơ chế hoạt động của Promise
Một Promise có 1 trong 3 trạng thái sau:
- pending: trạng thái khởi tạo
- fulfilled: có nghĩa thao tác đã hoàn thành thành công
- rejected: có nghĩa là thao tác thất bại
Một promise pending có thể thành fulfilled với kết quả, hoặc thành rejected với nguyên nhân (error). Khi option đó diễn ra, các handler liên quan sẽ thực hiện
Ví dụ: Ta sẽ thử viết 1 Promise hoàn chỉnh có then và catch
var promise = new Promise(function(resolve, reject) {
var value = Math.random()
if (value > 0.5) {
resolve(value)
}
reject('error')
});
promise.then(function(value) {
console.log(value)
}).catch(function(error) {
console.log(error)
})
Ta lấy 1 giá trị ngẫu nhiên, nếu lớn hơn 0.5 thì resolve nó ra, còn không thì reject lỗi
Ngoài ra, ta có thể viết như thế này:
var promise = new Promise(function(resolve, reject) {
var value = Math.random()
if (value > 0.5) {
resolve(value)
}
reject('error')
});
function onSuccess(value) { console.log(value) }
function onError(error) { console.log(error) }
promise.then(onSuccess, onError)
Tại sao phải sử dụng Promise?
Khi mà ta sử dụng callback function, ta phải viết callback xử lý tính toán ngay lập tức (khi mà thực hiện các thao tác bất đồng bộ) nên khi mà xảy ra quá nhiều thao tác bất đồng bộ đang diễn ra, sẽ dẫn đến tình trạng các callback function lồng vào nhau.
Còn ở Promise, nó làm 1 bản cam kết sẽ thực hiện trong tương lai, ta không cần phải viết xử lý then ngay lập tức mà có thể để promise object lại đến khi sau này cần mới thực hiện.
Ví dụ: Ta cần chạy lệnh bất đồng bộ nhưng chưa cần viết hàm xử lý khi có kết quả
var promise = new Promise(function(resolve, reject) {
setTimeout(function callback() {
console.log(8)
resolve(8)
}, 3000)
})
Khi chạy kết quả ta có thể thấy giá trị log 8 đã thực hiện, có nghĩa khi ta tạo một object promise, thì thao tác bất đồng bộ đã được thực hiện. Và khi resolve hay reject thì kết quả của xử lý bất đồng bộ này vẫn được lưu lại trong promise. Khi nào cần thì ta có thể viết hàm xử lý kết quả này.
Promise có thể hiểu là 1 biến chứa kết quả cuộc 1 lần thực hiện bất đồng bộ. Nó khác với các xử lý callback là ta có thể mang vác cái biến này đi khắp nơi trong code mà ta thấy phù hợp. Tại đó gọi hàm then chứa callback xử lý.
Vậy khi xử lý quá nhiều lệnh bất đồng bộ thì sao. lúc đó mỗi bất đồng bộ là một object promise, ta sẽ gom các promise này lại rồi xử lý tại promise all như sau:
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function callback() {
resolve(8)
}, 3000)
})
var promise2 = new Promise(function(resolve, reject) {
setTimeout(function callback() {
resolve(2)
}, 1000)
})
Promise.all([promise1, promise2]).then(function (values) {
console.log(values)
});
Như vậy, ta đã tránh được tình trạng callback hell khi có thể tách biệt các xử lý bất đồng bộ ra riêng cho đến khi tất cả kết quả bất đồng bộ đã có.
Lưu ý: Nếu trong một các promise có lỗi, thì promise.all sẽ xử lý phần catch thay vì xử lý then.
Promise chaining
Promise còn hỗ trợ cho chúng ta một kỹ thuật khá hay giúp ta kết nối các promise liên tiếp lại với nhau. Vì phương thức then (ở trường hợp promise thành công) khi return giá trị thì nó sẽ tạo một promise khác bọc lại giá trị đó, ta có thể tạo nên phương thức then phía sau để kết nối tiếp.
Ví dụ:
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
}).then(function(result) {
console.log('1:'+result)
return result + 1
}).then(function(result) {
console.log('2:'+result)
return new Promise(function(resolve, reject) {
setTimeout(() => resolve(result * 2), 1000);
});
}).then(function(result) {
console.log('3:'+result)
});
Lưu ý: Promise chaining phải cho các phương thức then nối liền nhau mới xử lý tuần tự. Tránh trường hợp viết như thế này:
var promise = new Promise(function(resolve, reject) {
setTimeout(function () { resolve(1) }, 1000);
})
promise.then(function(result) {
console.log(result); // 1
return result * 2;
});
promise.then(function(result) {
console.log(result); // 1
return result * 2;
});
promise.then(function(result) {
console.log(result); // 1
return result * 2;
});
Bản chất, ta đang viết 3 phương thức xử lý kết quả của promise đó:
Kết
Như vậy Kteam đã giới thiệu về Promise
Ở bài tiếp theo, Kteam sẽ giới thiệu cho các bạn Async/Await là gì?
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Promise là gì? dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Đừng quên like và share để ủng hộ Kteam và tác giả nhé!

Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.
Nội dung bài viết
Khóa học
Trong thời gian gần đây, JavaScript luôn là ngôn ngữ rất nhiều lập trình viên và sinh viên IT đang quan tâm và bàn tán vì tính linh hoạt, đa năng và cơ hội nghề nghiệp hấp dẫn mà ngôn ngữ này mang lại. Với sự phát triển nhanh các tính năng mới của JavaScript khiến nhiều người đang nghiên cứu cũng khó nhớ hết những tính năng và hiểu bản chất cụ thể của nó.
Thông qua khóa học SỔ TAY JAVASCRIPT, đây chỉ là những ghi chép mà Kteam tổng hợp như để có thể nghiên cứu lại khi cần thiết và giúp các bạn học hiểu được những tính năng JavaScript hiện nay.
mong có bài mới