?? 內(nèi)容速覽 ??
- 題目和答案
- 輸出解釋
- 再談?wù)刟sync/await
- 最新的v8和谷歌瀏覽器的正確輸出
專注前端與算法的系列干貨分享吟吝,歡迎關(guān)注(???):
「微信公眾號:心譚博客」| xin-tan.com | GitHub
1. 題目和答案
故事還是要從下面這道面試題說起:請問下面這段代碼的輸出是什么匀谣?
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
上述赠潦,在Chrome 66
和node v10
中,正確輸出是:
script start
async2 end
Promise
script end
promise1
promise2
async1 end
setTimeout
注意:在新版本的瀏覽器中,
await
輸出順序被“提前”了怎抛,請看官耐心慢慢看揍拆。
2. 流程解釋
邊看輸出結(jié)果拢操,邊做解釋吧:
- 正常輸出
script start
- 執(zhí)行
async1
函數(shù)锦亦,此函數(shù)中又調(diào)用了async2
函數(shù),輸出async2 end
令境「茉埃回到async1
函數(shù),遇到了await
舔庶,讓出線程抛蚁。 - 遇到
setTimeout
,扔到下一輪宏任務(wù)隊列 - 遇到
Promise
對象惕橙,立即執(zhí)行其函數(shù)瞧甩,輸出Promise
。其后的resolve
弥鹦,被扔到了微任務(wù)隊列 - 正常輸出
script end
- 此時肚逸,此次
Event Loop
宏任務(wù)都執(zhí)行完了。來看下第二步被扔進來的微任務(wù)彬坏,因為async2
函數(shù)是async
關(guān)鍵詞修飾朦促,因此,將await async2
后的代碼扔到微任務(wù)隊列中 - 執(zhí)行第4步被扔到微任務(wù)隊列的任務(wù)栓始,輸出
promise1
和promise2
- 執(zhí)行第6步被扔到微任務(wù)隊列的任務(wù)务冕,輸出
async1 end
- 第一輪EventLoop完成,執(zhí)行第二輪EventLoop幻赚。執(zhí)行
setTimeout
中的回調(diào)函數(shù)禀忆,輸出setTimeout
。
3. 再談async和await
細心的朋友肯定會發(fā)現(xiàn)前面第6步落恼,如果async2
函數(shù)是沒有async
關(guān)鍵詞修飾的一個普通函數(shù)呢箩退?
// 新的async2函數(shù)
function async2() {
console.log('async2 end')
}
輸出結(jié)果如下所示:
script start
async2 end
Promise
script end
async1 end
promise1
promise2
setTimeout
不同的結(jié)果就出現(xiàn)在前面所說的第6步:如果await函數(shù)后面的函數(shù)是普通函數(shù),那么其后的微任務(wù)就正常執(zhí)行佳谦;否則乏德,會將其再放入微任務(wù)隊列。
4. 其實是V8引擎的BUG
看到前面吠昭,正常人都會覺得真奇怪!(但是按照上面的訣竅倒也是可以理解)
然而V8團隊確定了這是個bug(很多強行解釋要被打臉了)胧瓜,具體的PR請看這里矢棚。好在,這個問題已經(jīng)在最新的Chrome瀏覽器中被修復(fù)了府喳。
簡單點說蒲肋,前面兩段不同代碼的運行結(jié)果都是:
script start
async2 end
Promise
script end
async1 end
promise1
promise2
setTimeout
await
就是讓出線程,其后的代碼放入微任務(wù)隊列(不會再多一次放入的過程),就這么簡單了兜粘。
更多系列文章
專注前端與算法的系列干貨分享申窘,歡迎關(guān)注(???)
image