一道關(guān)于js宏任務(wù)、微任務(wù)面試題引發(fā)的思考

先看面試題

async function async1(){
    console.log('1')
    await async2()
    console.log('2')
}
async function async2(){
    console.log('3')
}
console.log('4')
setTimeout(function(){
    console.log('5') 
},0)  
async1();
new Promise(function(resolve){
    console.log('6')
    resolve();
}).then(function(){
    console.log('7')
})
console.log('8')

上面的題,答案是什么呢?
答案是:4,1,3,6,8,2,7,5

懵逼了嗎?反正我第一次接觸看到這個(gè)面試時(shí)候是一臉懵,好吧,繼續(xù)說(shuō)。
javascript是單線(xiàn)程,所以只有唯一的事件循環(huán),這個(gè)時(shí)候js就把所有任務(wù)分為了兩種:同步任務(wù)和異步任務(wù)。
而異步任務(wù)的兩種分類(lèi)分別為:宏任務(wù)和微任務(wù)。

同步任務(wù):就是在主線(xiàn)程上排隊(duì)執(zhí)行的任務(wù),只有在前面的任務(wù)執(zhí)行完后,才能執(zhí)行后面的任務(wù);

異步任務(wù):是指不進(jìn)入主線(xiàn)程,而是進(jìn)入“任務(wù)隊(duì)列”的任務(wù),只有"任務(wù)隊(duì)列"通知主線(xiàn)程,某個(gè)異步任務(wù)可以執(zhí)行了,該任務(wù)才會(huì)進(jìn)入主線(xiàn)程執(zhí)行。

事件循環(huán)EventLoop
是JS的執(zhí)行機(jī)制,是指同步任務(wù)進(jìn)入主線(xiàn)程后,而異步任務(wù)進(jìn)入Event Table注冊(cè)函數(shù),當(dāng)異步事件完成后,會(huì)將回調(diào)函數(shù)放入Event Queue中,當(dāng)同步任務(wù)完成后,會(huì)從Event Queue中讀取事件放入主線(xiàn)程執(zhí)行,這個(gè)過(guò)程不斷循環(huán)執(zhí)行。

事件的執(zhí)行順序是先執(zhí)行宏任務(wù),然后執(zhí)行微任務(wù)。微任務(wù)按先進(jìn)先出的順序執(zhí)行;微任務(wù)清空后再執(zhí)行宏任務(wù),按先進(jìn)先出的順序取出執(zhí)行。

如下圖:


image.png

image.png

宏任務(wù):包括整體代碼script,setTimeout,setInterval
微任務(wù):Promise.then(非new Promise),process.nextTick(node中)

下面我們就來(lái)看一下上面的結(jié)果是怎么得出來(lái)的吧!
1.先打印4,這個(gè)就不說(shuō)了;
2.走到setTimeout,是一個(gè)宏任務(wù),它要先等當(dāng)前的宏任務(wù)結(jié)束后再執(zhí)行;
3.async1();執(zhí)行該函數(shù),先打印1,然后執(zhí)行async2()函數(shù),打印3,因?yàn)閍sync2函數(shù)前面有await關(guān)鍵字,會(huì)隱式返回promise微任務(wù),進(jìn)入回調(diào)隊(duì)列;
4.執(zhí)行new promise,同步任務(wù),先打印6,后面.then()微任務(wù)進(jìn)入回調(diào)隊(duì)列;
5.打印8,此時(shí)同步任務(wù)執(zhí)行完畢,讀取任務(wù)隊(duì)列,進(jìn)入主線(xiàn)程執(zhí)行;
6.還記得微任務(wù)先進(jìn)先出的順序吧,此時(shí)先執(zhí)行async2返回的一個(gè)promise,打印2;
7.接著到promise.then(),打印出7;
8.到這里當(dāng)前的宏任務(wù)結(jié)束,執(zhí)行下一輪的宏任務(wù)setTimeout,所以最后打印出5;

最終結(jié)果就是4.1.3.6.8.2.7.5

再說(shuō)一下函數(shù)前面多了一個(gè)aync關(guān)鍵字。
await關(guān)鍵字只能用在aync定義的函數(shù)內(nèi),async函數(shù)會(huì)隱式地返回一個(gè)promise。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容