JavaScript事件循環(huán)及宏任務(wù)微任務(wù)原理解析
首先看一段代碼:

打印順序是什么?
正確答案:script start, script end, promise1, promise2, setTimeout
其中涉及到事件循環(huán)(event loop),宏任務(wù)(macrotask),微任務(wù)(microtask)
一、事件循環(huán) Event Loop
程序中設(shè)置兩個線程:一個負(fù)責(zé)程序本身的運(yùn)行,稱為'主線程';另一個負(fù)責(zé)主線程與其他進(jìn)程(主要是各種I/O操作)的通信,被稱為'Event Loop線程'(可以譯為'消息線程')。
所有任務(wù)可以分成兩種,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous)。
同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù);
異步任務(wù)指的是,不進(jìn)入主線程、而進(jìn)入'任務(wù)隊(duì)列'(task queue)的任務(wù),只有'任務(wù)隊(duì)列'通知主線程,某個異步任務(wù)可以執(zhí)行了,該任務(wù)才會進(jìn)入主線程執(zhí)行。
一般而言,異步任務(wù)有以下三種類型:
1、普通事件,如click、resize等

2、資源加載,如load、error等

3、定時器,包括setInterval、setTimeout等

事件循環(huán)具體過程就是:
同步任務(wù)進(jìn)入主線程,異步任務(wù)進(jìn)入Event Table并注冊函數(shù)。 當(dāng)異步任務(wù)完成時,Event Table會將這個函數(shù)移入Event Queue。 主線程內(nèi)的任務(wù)執(zhí)行完畢執(zhí)行棧為空,會去Event Queue讀取對應(yīng)的函數(shù),進(jìn)入主線程執(zhí)行。 上述過程會不斷重復(fù),也就是常說的Event Loop(事件循環(huán))。二、宏任務(wù)與微任務(wù)
在JavaScript中,任務(wù)被分為兩種,一種宏任務(wù)(MacroTask),一種叫微任務(wù)(MicroTask)。
2.1MacroTask(宏任務(wù))
宿主環(huán)境提供的(瀏覽器和node)
script全部代碼、setTimeout、setInterval。
瀏覽器為了能夠使得JS內(nèi)部task與DOM任務(wù)能夠有序的執(zhí)行,會在一個task執(zhí)行結(jié)束后,在下一個 task 執(zhí)行開始前,對頁面進(jìn)行重新渲染 (task->渲染->task->...)
2.2MicroTask(微任務(wù))
語言標(biāo)準(zhǔn)提供的
Promise、await
async函數(shù)表示函數(shù)里面可能會有異步方法,await后面跟一個表達(dá)式,async方法執(zhí)行時,遇到await會立即執(zhí)行表達(dá)式,然后把a(bǔ)wait表達(dá)式后面的代碼放到微任務(wù)隊(duì)列里,讓出執(zhí)行棧讓同步代碼先執(zhí)行
async function foo() { var a = await new Promise((resolve) => { setTimeout(() => { resolve(1); }, 2000); }); console.log(a); // 第2秒時輸出: 1}foo();
2.3宏任務(wù)與微任務(wù)執(zhí)行順序:
執(zhí)行棧在執(zhí)行完同步任務(wù)后,查看執(zhí)行棧是否為空,如果執(zhí)行棧為空,就會去檢查微任務(wù)隊(duì)列是否為空,如果為空的話,就執(zhí)行宏任務(wù),否則就一次性執(zhí)行完所有微任務(wù)。 每次單個宏任務(wù)執(zhí)行完畢后,檢查微任務(wù)隊(duì)列是否為空,如果不為空的話,會按照先入先出的規(guī)則全部執(zhí)行完微任務(wù)后,設(shè)置微任務(wù)隊(duì)列為null,然后再執(zhí)行宏任務(wù),如此循環(huán)。總結(jié):同步—>微任務(wù)—>宏任務(wù)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. 理解PHP5中static和const關(guān)鍵字2. IntelliJ IDEA安裝插件的方法步驟3. php模擬實(shí)現(xiàn)斗地主發(fā)牌4. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟5. Vue封裝一個TodoList的案例與瀏覽器本地緩存的應(yīng)用實(shí)現(xiàn)6. jQuery 實(shí)現(xiàn)DOM元素拖拽交換位置的實(shí)例代碼7. Vuex localStorage的具體使用8. vue 使用localstorage實(shí)現(xiàn)面包屑的操作9. spring acegi security 1.0.0 發(fā)布10. MyBatis中的JdbcType映射使用詳解

網(wǎng)公網(wǎng)安備