2017-09-16 63 views
0

我有這段代碼:承諾解析順序伺機

af = async() => { 
 
    Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

在谷歌的Chrome版本61.0.3163.91(正式版本)(64位) 當我運行它從一個<script>,我得到了以下結果:

first then 
after await 
second then 

但是當我複製/粘貼代碼到控制檯,並運行它有:

first then 
second then 
after await 

node.js 8.5.0的行爲相似。

什麼是正確的順序和爲什麼有區別?

//編輯

另一個有趣的事情是,火狐55.0.2(64位) 此代碼:

af = async() => { 
 
    Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    .then(x => console.log("third then")) 
 
    .then(x => console.log("forth then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

日誌:

first then 
second then 
third then 
after await 
forth then 
+0

如果多個'。然後()'處理程序都在一個'await'後同時事項的隊列(和代碼的精確的順序是非常相同一個'.then()'處理程序),那麼你的代碼應該寫成你自己控制順序,而不是完全依賴於promise調度程序的命令。而且,我甚至不確定你問的是實際寫入規範。無論如何,大多數真正的實現都會有不確定時間的承諾背後的異步操作。 – jfriend00

+0

準確而精確的答案很可能會非常長,並取決於未指定的實現細節。查看DOMContentLoaded的步驟,例如https://html.spec.whatwg.org/multipage/parsing.html#the-end –

+0

不知道爲什麼,但它可能是一個提示: 如果您全部替換你用數組推動日誌,然後登錄你的最終陣列,訂單總是 ['1 then','2 then','await] 也許是一個console.log不一致的行爲? –

回答

0

doin的正確方法g這是在Promise.resolve()之前添加一個await,它執行「首先然後」和「然後再次」控制檯日誌。這樣它就會等待承諾完成,然後再移到控制檯日誌中以便「等待」後

這就是你要這麼做的方法。

af = async() => { 
 
    await Promise.resolve() // NOTE: I added a "await" before the Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

+0

我沒有要求在底部console.log之前讓兩個'then'都被解析。我想知道這種情況下的調度算法(在第二個'then「回調之前或之後的'await') – marzelin

+0

您是什麼意思的調度算法? – user3254198

+0

支配回調添加到消息隊列的順序的規則 – marzelin