Lần thử thứ hai với một câu trả lời mà tôi cố gắng giải thích rõ hơn:
Đầu tiên, một số thông tin cơ bản cần thiết, từ RSVP README :
Phần thực sự tuyệt vời đến khi bạn trả lại một lời hứa từ trình xử lý đầu tiên ... Điều này cho phép bạn làm phẳng các lệnh gọi lại lồng nhau và là tính năng chính của các lời hứa ngăn chặn "lệch phải" trong các chương trình có nhiều mã không đồng bộ.
Đây chính là cách bạn thực hiện các lời hứa một cách tuần tự, bằng cách trả lại lời hứa sau đó từ then
lời hứa sẽ kết thúc trước nó.
Sẽ rất hữu ích khi nghĩ về một tập hợp các lời hứa như một cái cây, trong đó các nhánh biểu thị các quá trình tuần tự và các lá biểu thị các quá trình đồng thời.
Quá trình xây dựng một cây hứa hẹn tương tự như nhiệm vụ rất phổ biến của việc xây dựng các loại cây khác: duy trì một con trỏ hoặc tham chiếu đến vị trí trong cây mà bạn hiện đang thêm các nhánh và lặp đi lặp lại thêm các thứ.
Như @Esailija đã chỉ ra trong câu trả lời của mình, nếu bạn có một mảng các hàm trả về lời hứa không nhận đối số, bạn có thể sử dụng reduce
để xây dựng cây một cách gọn gàng cho mình. Nếu bạn đã từng thực hiện giảm cho chính mình, bạn sẽ hiểu rằng những gì giảm đang làm đằng sau hậu trường trong câu trả lời của @ Esailija là duy trì một tham chiếu đến lời hứa hiện tại ( cur
) và mỗi lời hứa trả lại lời hứa tiếp theo trong nó then
.
Nếu bạn KHÔNG có một mảng thuần nhất đẹp đẽ (đối với các đối số mà chúng lấy / trả về) các hàm trả về hứa hẹn hoặc nếu bạn cần một cấu trúc phức tạp hơn một chuỗi tuyến tính đơn giản, bạn có thể tự xây dựng cây các hứa hẹn bằng cách duy trì tham chiếu đến vị trí trong cây hứa hẹn nơi bạn muốn thêm các lời hứa mới:
var root_promise = current_promise = Ember.Deferred.create();
current_promise = current_promise.then(function(){
return
});
current_promise = current_promise.then(function(){
return
});
root_promise.resolve();
Bạn có thể xây dựng kết hợp các quy trình đồng thời và tuần tự bằng cách sử dụng RSVP.all để thêm nhiều "lá" vào một "nhánh" lời hứa. Câu trả lời không-vì-quá-phức tạp của tôi cho thấy một ví dụ về điều đó.
Bạn cũng có thể sử dụng Ember.run.scheduleOnce ('afterRender') để đảm bảo rằng điều gì đó được thực hiện trong một lời hứa sẽ được hiển thị trước khi lời hứa tiếp theo được thực hiện - câu trả lời quá phức tạp của tôi cũng cho thấy một ví dụ về điều đó.