Có, Lời hứa là cuộc gọi lại không đồng bộ. Họ không thể làm bất cứ điều gì mà cuộc gọi lại không thể làm được và bạn phải đối mặt với những vấn đề tương tự với sự không đồng bộ như với cuộc gọi lại đơn giản.
Tuy nhiên, lời hứa là nhiều hơn chỉ là callbacks. Chúng là một sự trừu tượng hóa rất mạnh mẽ, cho phép mã chức năng sạch hơn và tốt hơn, với bản tóm tắt ít bị lỗi hơn.
Vậy ý chính là gì?
Hứa hẹn là các đối tượng đại diện cho kết quả của một tính toán (không đồng bộ). Họ giải quyết kết quả đó chỉ một lần. Có một vài điều điều này có nghĩa là:
Hứa hẹn thực hiện một mô hình quan sát viên:
- Bạn không cần phải biết các cuộc gọi lại sẽ sử dụng giá trị trước khi tác vụ hoàn thành.
- Thay vì mong đợi các cuộc gọi lại làm đối số cho các chức năng của bạn, bạn có thể dễ dàng trở
return
thành một đối tượng Promise
- Lời hứa sẽ lưu trữ các giá trị, và bạn có thể minh bạch thêm một callback bất cứ khi nào bạn muốn. Nó sẽ được gọi khi kết quả có sẵn. "Tính minh bạch" ngụ ý rằng khi bạn có một lời hứa và thêm một cuộc gọi lại cho nó, điều đó sẽ không tạo ra sự khác biệt cho mã của bạn cho dù kết quả đã đến chưa - API và các hợp đồng giống nhau, đơn giản hóa rất nhiều bộ nhớ đệm / ghi nhớ.
- Bạn có thể thêm nhiều cuộc gọi lại dễ dàng
Lời hứa có thể kết nối ( đơn âm , nếu bạn muốn ):
- Nếu bạn cần chuyển đổi giá trị mà một lời hứa thể hiện, bạn ánh xạ một hàm biến đổi theo lời hứa và nhận lại một lời hứa mới thể hiện kết quả được chuyển đổi. Bạn không thể đồng bộ hóa giá trị để sử dụng nó bằng cách nào đó, nhưng bạn có thể dễ dàng nâng chuyển đổi trong bối cảnh hứa hẹn. Không có cuộc gọi lại nồi hơi.
- Nếu bạn muốn xâu chuỗi hai tác vụ không đồng bộ, bạn có thể sử dụng
.then()
phương thức. Nó sẽ nhận một cuộc gọi lại để được gọi với kết quả đầu tiên và trả lại một lời hứa cho kết quả của lời hứa mà cuộc gọi lại trả về.
Nghe có vẻ phức tạp? Thời gian cho một ví dụ mã.
var p1 = api1(); // returning a promise
var p3 = p1.then(function(api1Result) {
var p2 = api2(); // returning a promise
return p2; // The result of p2 …
}); // … becomes the result of p3
// So it does not make a difference whether you write
api1().then(function(api1Result) {
return api2().then(console.log)
})
// or the flattened version
api1().then(function(api1Result) {
return api2();
}).then(console.log)
Làm phẳng không đến một cách kỳ diệu, nhưng bạn có thể dễ dàng làm điều đó. Đối với ví dụ được lồng rất nhiều của bạn, tương đương (gần) sẽ là
api1().then(api2).then(api3).then(/* do-work-callback */);
Nếu việc xem mã của các phương thức này giúp hiểu, thì đây là một lời hứa cơ bản nhất trong một vài dòng .
Những gì ồn ào về những lời hứa?
Sự trừu tượng hóa Promise cho phép khả năng kết hợp tốt hơn nhiều chức năng. Ví dụ, bên cạnh then
chuỗi, all
hàm tạo ra một lời hứa cho kết quả kết hợp của nhiều lời hứa chờ song song.
Lời hứa cuối cùng nhưng không kém phần quan trọng đi kèm với việc xử lý lỗi tích hợp. Kết quả của việc tính toán có thể là một trong hai lời hứa được thực hiện với một giá trị hoặc nó bị từ chối với một lý do. Tất cả các hàm thành phần tự động xử lý việc này và truyền các lỗi trong chuỗi hứa hẹn, do đó bạn không cần quan tâm đến nó một cách rõ ràng ở mọi nơi - ngược lại với việc thực hiện gọi lại đơn giản. Cuối cùng, bạn có thể thêm một cuộc gọi lại lỗi chuyên dụng cho tất cả các trường hợp ngoại lệ xảy ra.
Chưa kể phải chuyển đổi mọi thứ thành lời hứa.
Điều đó thực sự khá tầm thường với các thư viện hứa hẹn tốt, hãy xem Làm cách nào để chuyển đổi API gọi lại hiện tại thành các lời hứa?