[英]Add an undefined method promise to an array to be resolved later in Promise.all()
[英]Why the Promise.all(array) not resolved immediately?
我在我的機器上運行代碼示例(安裝了Node 5.8.0)並獲得下一個結果(參見代碼示例)。
代碼示例:
'use strict'
var p1 = Promise.resolve();
var p2 = Promise.resolve();
var p12 = Promise.all([p1, p2]);
var cb = function() {
console.log(p12);
}
setTimeout(cb, 0);
console.log(p1);
console.log(p2);
console.log(p12);
結果:
承諾{undefined}
承諾{undefined}
承諾{ <pending>
}
承諾{[undefined,undefined]}
為什么在p1和p2之后沒有立即解析p12(在程序開始時解析p1和p1),為什么“timeouted”p12得到解決? Promise.all(數組)需要一些時間才能得到解決嗎?
根據promise規范,在事件循環完成當前循環后,始終異步調用promise履行或拒絕處理程序。 因此,即使對它的參數都是已解決的promise, p12
也不會立即解析。 因此,直到此事件循環結束后不久,它才會得到解決。 這解釋了為什么你的第一個聲明
console.log(p12);
表明承諾仍然“待定”。 它是當前的.then()
處理程序(如果有的話)還沒有被調用。 但是,一旦當前的代碼線程完成執行並且控制返回到事件隊列中的下一個事件,則將解析promise,因此你的setTimeout()
將其視為已解決。
這是出於調用者一致性原因而完成的,因此無論promise已經解決還是尚未解決,都會以異步方式一致地調用.then()
處理程序。 這允許調用代碼始終一致地編碼,而不必擔心承諾是否已經解決。 在所有情況下.then()
處理程序在當前堆棧展開並完成后調用。
來自Promises / A +規范 :
在執行上下文堆棧僅包含平台代碼之前,不得調用onFulfilled或onRejected。
這里的“平台代碼”意味着引擎,環境和承諾實現代碼。 實際上,這個要求確保onFulfilled和onRejected異步執行,然后調用事件循環,然后調用新堆棧。 這可以使用諸如setTimeout或setImmediate之類的“宏任務”機制,或者使用諸如MutationObserver或process.nextTick之類的“微任務”機制來實現。 由於promise實現被認為是平台代碼,因此它本身可能包含一個任務調度隊列或“trampoline”,其中調用處理程序。
因此,所有這一切的結果是承諾總是在當前執行線程完成后異步解析。 雖然內部細節可能比這更復雜(可能涉及微任務),但您可以通過在事件隊列中發布消息來邏輯地考慮通過現在正在等待解析/拒絕的消息來解決。 並且,每當事件隊列完成當前正在運行的內容並輪到運行promises .then()
處理程序時,它們才會執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.