Event Loop我知道,宏任務(wù)微任務(wù)是什么鬼?

在介紹宏任務(wù)和微任務(wù)之前,先拋出一個(gè)問(wèn)題。相信大家在面試的時(shí)候,會(huì)遇到這樣的相似的問(wèn)題:

setTimeout(function(){

console.log('1')

});

new  Promise(function(resolve){

  console.log('2');

  resolve();

}).then(function(){

console.log('3')

});

console.log('4');

 

請(qǐng)說(shuō)出控制臺(tái)打印的數(shù)據(jù),很多小伙伴經(jīng)過(guò)深思熟慮之后,會(huì)自信的說(shuō)出答案:2、4、1、3。

但是說(shuō)出答案之后往往會(huì)發(fā)現(xiàn)面試官并沒(méi)有出現(xiàn)很滿意的表情。這是為什么呢?接下來(lái)讓我們一步一步的探討面試官不滿意的原因。
JavaScript事件循環(huán)機(jī)制

首先還是說(shuō)說(shuō)JavaScript的事件循環(huán)機(jī)制,大家都知道,js的執(zhí)行任務(wù)分為同步任務(wù)和異步任務(wù),那么他們的執(zhí)行情況是怎么樣的尼?執(zhí)行的時(shí)候,會(huì)優(yōu)先執(zhí)行同步任務(wù),當(dāng)執(zhí)行中遇到了異步任務(wù),會(huì)暫時(shí)將異步任務(wù)扔到異步隊(duì)列中,繼續(xù)執(zhí)行后面的同步任務(wù)。當(dāng)所有的同步任務(wù)執(zhí)行完成之后,再執(zhí)行剛才扔在異步隊(duì)列中的任務(wù)。一直循環(huán)執(zhí)行,也就形成了我們JavaScript的Event Loop機(jī)制。

可能純文字的介紹大家看得有點(diǎn)繞,下面引入一張圖片來(lái)幫助大家理解JavaScript事件循環(huán)機(jī)制:












































在這里插入圖片描述

看完這個(gè)圖,各位小伙伴可能會(huì)覺得,我上面的答案沒(méi)有問(wèn)題呀,是正確的呀!但是事情并不是那么的簡(jiǎn)單,接下來(lái)引入兩個(gè)新概念:宏任務(wù)(macrotask)和微任務(wù)(microtask)
宏任務(wù)(macrotask)和微任務(wù)(microtask)

宏任務(wù)和微任務(wù)表示的是異步任務(wù)的兩種分類。在瀏覽器js引擎加載js代碼的時(shí)候,會(huì)將所有的代碼以任務(wù)的形式分別分配到這兩個(gè)分類的隊(duì)列中。然后首先會(huì)從宏任務(wù)的任務(wù)隊(duì)列中中取出一條任務(wù)執(zhí)行;當(dāng)執(zhí)行完畢之后再將微任務(wù)隊(duì)列里面的所有的任務(wù)按照順序執(zhí)行;當(dāng)所有的微任務(wù)隊(duì)列任務(wù)執(zhí)行完畢之后,再去宏任務(wù)隊(duì)列中取出一條任務(wù)執(zhí)行。

宏任務(wù)主要有:整體script代碼、setTimeout、setInterval、I/O、requestAnimationFrame
微任務(wù)主要有:Promise、process.nextTick、MutationObserver

那么宏任務(wù)和微任務(wù)到底是什么關(guān)系呢?接下來(lái),奉上一張寶圖,描述兩者的關(guān)系:



































在這里插入圖片描述

相信,看到這里,大家已經(jīng)知道上面的問(wèn)題的答案了吧,沒(méi)錯(cuò),就是2、4、3、1。

歡迎關(guān)注微信公眾號(hào):猴哥說(shuō)前端