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