上一次文章 異步操作和事件循環(huán)機制(Event Loop)中我們提到了 EventLoop ,而事件循環(huán)機制在 Node.js 與 瀏覽器中均存在,今天我們來看一下瀏覽器中的EventLoop
回顧:
- 屬于微任務(wù)的事件有:
process.nextTick、promise、MutationObserver - 屬于宏任務(wù)的事件有
script、setTimeout、setInterval、setImmediate、I/O、UI rendering -
EventLoop 隊列中存放的均是異步代碼
瀏覽器中的EventLoop
-
代碼一:代碼段1
問:以上代碼的輸出的結(jié)果是什么?
分析:
- 代碼執(zhí)行第一句,發(fā)現(xiàn)是 一個
setTimeout,是一個異步任務(wù),故將其放入EventLoop中,又setTimeout為宏任務(wù),故將其放入宏任務(wù)隊列中。
此時,宏任務(wù)隊列:function(){console.log(4)} - 執(zhí)行第四句代碼;執(zhí)行第五句代碼,
輸出數(shù)字 1;Promise后的then為異步代碼,執(zhí)行第六句代碼,將.then(function(){console.log(5)})放入微任務(wù)隊列中
此時,微任務(wù)隊列:function(){console.log(5)} - 執(zhí)行第七句代碼,
輸出數(shù)字5 - 執(zhí)行第十一句代碼,
輸出數(shù)字 3,至此,同步代碼執(zhí)行完畢,接下來進入EventLoop階段 - 首先執(zhí)行的是微任務(wù)隊列中的回調(diào)函數(shù),即執(zhí)行
function(){console.log(5)},輸出數(shù)字5,繼續(xù)看微任務(wù)隊列中是否還有回調(diào)函數(shù),有的話就繼續(xù)執(zhí)行微隊列中的回調(diào)函數(shù),隊列遵循先進先出的原則 - 執(zhí)行完微任務(wù),去執(zhí)行宏任務(wù)中的回調(diào)函數(shù),即執(zhí)行
.then(function(){console.log(5)}),輸出數(shù)字4。
至此,整段代碼就全部執(zhí)行結(jié)束,輸出結(jié)果:1、2、3、5、4
-
代碼二:代碼2
問:以上代碼的輸出的結(jié)果是什么?
分析:
-
async ..... await為一個Promise的語法糖,功能是使異步代碼看起來像是以同步的方式執(zhí)行的,await fn后面的代碼',要等fn執(zhí)行完后才能執(zhí)行,即碰到await fn相關(guān)的代碼可改寫成fn.then(后面的代碼) - 第一行到第八行均為函數(shù)聲明,從第九行開始執(zhí)行。進入
async1,轉(zhuǎn)到第一行開始執(zhí)行,執(zhí)行第二行輸出數(shù)字1,執(zhí)行第三行代碼,碰到await async2(),將第三第四行代碼改寫成async2().then(()=>{console.log(2)}),執(zhí)行async2()轉(zhuǎn)到第六行,第七行輸出數(shù)字3,將后面的.then(()=>{console.log(2)})放入微任務(wù)隊列中。
此時,微任務(wù)隊列:console.log(2) - 開始執(zhí)行第十行代碼,第十一行
輸出數(shù)字4,將.then(function(){console.log(5)})放入微任務(wù)隊列中
此時,微任務(wù)隊列:console.log(5)、console.log(2) - 至此,同步代碼執(zhí)行完畢,接下來進入
EventLoop階段 - 執(zhí)行 微任務(wù),隊列遵循先進先出原則,故先執(zhí)行
console.log(2),輸出數(shù)字2;再執(zhí)隊列中的console.log(5),輸出數(shù)字5。 - 至此,整個代碼塊執(zhí)行完畢,
輸出結(jié)果:1、3、4、2、5
總結(jié):瀏覽器中的EventLoop,先執(zhí)行微任務(wù),將微任務(wù)隊列中的回調(diào)函數(shù)執(zhí)行完,再執(zhí)行宏任務(wù)。隊列遵循先進先出原則
下一篇文章寫node.js中的 EventLoop

