2015-07-04 15 views
6

Tôi không hiểu tại sao lại bị trì hoãn Yêu cầu trì hoãn .then() cuộc gọi đối số?Tại sao Promise.resolve(). Sau đó() bị trì hoãn?

dụ:

var myPromise = Promise.resolve(); 
console.log(myPromise); 
myPromise.then(()=>console.log('a')); 
console.log('b'); 

console trở lại:

> Promise { <state>: "fulfilled", <value>: undefined } 
> "b" 
> "a" 

Nếu myPromise được hoàn thành, tại sao .then() không gọi imediatly giải quyết chức năng?

Trả lời

6

Bởi vì, theo đặc điểm kỹ thuật, hứa hẹn sẽ gọi trình xử lý giải quyết của họ SAU khi luồng hiện tại thực hiện bung ra và kết thúc lại thành "mã nền tảng". Điều đó đảm bảo rằng chúng luôn được gọi là không đồng bộ.

Vì vậy, do đó bạn nhìn thấy console.log('b') trước tiên khi chuỗi đó thực hiện kết thúc và sau đó trình xử lý giải quyết được gọi là nơi bạn xem console.log('a').

Từ Promises/A+ specification:

2.2.4 onFulfilled hoặc onRejected phải không được gọi cho đến khi thực hiện bối cảnh chồng chỉ chứa mã nền tảng. [3.1].

Và, đây là lưu ý [3.1]:

Here “nền tảng mã” nghĩa là công cụ, môi trường, và hứa mã thực hiện. Trong thực tế, yêu cầu này đảm bảo rằng onFulfilled và onRejected thực hiện không đồng bộ, sau sự kiện vòng lặp trong đó được gọi, và với một ngăn xếp mới. Đây có thể là được triển khai bằng cơ chế “tác vụ macro” như setTimeout hoặc setImmediate hoặc với cơ chế “vi nhiệm vụ” chẳng hạn như MutationObserver hoặc process.nextTick. Kể từ khi triển khai lời hứa được coi là mã nền tảng, bản thân nó có thể chứa một xếp hàng nhiệm vụ hàng đợi hoặc “tấm bạt lò xo” trong đó các trình xử lý được gọi.

này được thực hiện để cung cấp phù hợp để thực hiện vì vậy không có vấn đề khi sự hứa hẹn được giải quyết (đồng bộ hoặc không đồng bộ), các then() xử lý luôn luôn được gọi trong thời gian tương tự so với các mã khác. Vì nhiều lời hứa được giải quyết không đồng bộ, cách duy nhất để thực hiện một lời hứa nhất quán bất kể nó được giải quyết như thế nào là làm cho chúng luôn gọi trình xử lý .then() của chúng không đồng bộ.

5

câu trả lời của jfriend00 là chính xác. Cho phép tôi giải thích tại sao. Giả sử tôi có myPromise từ đâu đó. Tôi không biết đó chỉ là một số Promise.resolve, nó có thể giải quyết không đồng bộ và có thể không.

myPromise.then(function(){ 
    console.log("a"); 
}); 
console.log("b"); 

Nếu bảo lãnh asynchronousity không tồn tại - đó sẽ đôi khi log a b và đôi khi b a. Đây là điều kiện chạy đua và là terrible thing to have.Lời hứa không dễ bị vấn đề này bởi thiết kế - và trật tự thực hiện là luôn được bảo đảm trong các triển khai hứa hẹn mới và lời hứa gốc cụ thể là.

Việc triển khai thực tế việc chạy công việc mới là via Job Queues. then enqueues một công việc để hàng đợi công việc trong xử lý, và hàng đợi công việc được chạy sau khi mã đã sẵn sàng - điều này được quy định here.

Các vấn đề liên quan