因?yàn)?js 是單線程運(yùn)行的,在代碼執(zhí)行時(shí),通過將不同函數(shù)的執(zhí)行上下文壓入執(zhí)行棧中來(lái)保證代碼的有序執(zhí)行。在執(zhí)行同步代碼時(shí),如果遇到異步事件,js 引擎并不會(huì)一直等待其返回結(jié)果,而是會(huì)將這個(gè)事件掛起,繼續(xù)執(zhí)行執(zhí)行棧中的其他任務(wù)。當(dāng)異步事件執(zhí)行完畢后,再將異步事件對(duì)應(yīng)的回調(diào)加入到一個(gè)任務(wù)隊(duì)列中等待執(zhí)行。任務(wù)隊(duì)列可以分為宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列,當(dāng)當(dāng)前執(zhí)行棧中的事件執(zhí)行完畢后,js 引擎首先會(huì)判斷微任務(wù)隊(duì)列中是否有任務(wù)可以執(zhí)行,如果有就將微任務(wù)隊(duì)首的事件壓入棧中執(zhí)行。當(dāng)微任務(wù)隊(duì)列中的任務(wù)都執(zhí)行完成后再去執(zhí)行宏任務(wù)隊(duì)列中的任務(wù)。
Event Loop 執(zhí)行順序如下所示:首先執(zhí)行同步代碼,這屬于宏任務(wù)當(dāng)執(zhí)行完所有同步代碼后,執(zhí)行棧為空,查詢是否有異步代碼需要執(zhí)行執(zhí)行所有微任務(wù)當(dāng)執(zhí)行完所有微任務(wù)后,如有必要會(huì)渲染頁(yè)面然后開始下一輪 Event Loop,執(zhí)行宏任務(wù)中的異步代碼