![](/img/trans.png)
[英]Clarification on order of Promise resolution using Async/Await
[英]Async resolution order for await single promise vs async iterators
因此,這是基於我在處理包以簡化異步生成器或迭代器時所做的發現。
通常,promise 的執行順序由它被調用的時間決定,這意味着以下是正確的(在 Windows 和 Mac 上的 Chrome 和 Node 中)。
let resolve, promise = new Promise(r => resolve = r);
(async () => {
await promise
console.log('1st')
})();
(async () => {
await promise
console.log('2nd')
})();
resolve();
但是,在處理異步生成器或迭代器時不遵守此順序
let resolve, promise = new Promise(r => resolve = r);
async function* generator() {
yield promise
}
(async () => { // regular promise
await promise
console.log('1st')
})();
(async () => { // promise generator
for await (let _ of generator())
console.log('3rd (should be 2nd)')
})();
(async () => { // promise iterator
for await (let _ of [promise])
console.log('4th (should be 3rd)')
})();
(async () => { // regular promise again
await promise
console.log('2nd (should be 4th)')
})();
resolve();
我不確定“執行/解決順序”是否是正確的術語,但是這個順序是否有保證? 有什么辦法可以在節點或瀏覽器程序中保證這個順序嗎?
Promise 解析順序是有保證的:
25.6.1.8 TriggerPromiseReactions(反應,參數)
[...]
對於在反應中各反應中,在原來的插入順序,執行
一種。 執行 EnqueueJob("PromiseJobs", PromiseReactionJob, << reaction, arguments >>)
要了解迭代器發生了什么,請查看以下代碼段:
let resolve, promise = new Promise(r => resolve = r); let chained = promise.then(it => Promise.resolve()); (async () => { await chained; console.log("2nd"); })(); (async () => { // regular promise await promise console.log('1st') })(); resolve();
如您所見,當另一個 Promise 解決時,一個 Promise 得到解決需要兩個 microticks。
這就是異步迭代器中發生的事情。 當您調用.next
,會返回一個 Promise 並存儲在迭代器內部隊列中。 同時,異步生成器函數的執行還在繼續。 然后,當異步迭代器yields
(在您的情況下是在一個 microtick 之后),它會解析隊列中的下一個承諾。 由於承諾解析是另一個微任務,所以總共需要兩個滴答。
resolve();
// 1 microtick
await promise; // generators await yielded promises implicitly
yield;
// 1 microtick
for await(const _ of iterator)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.