JS的事件循環(huán)

為什么有事件循環(huán)

-JS單線程
JavaScript設(shè)計(jì)之初就是單線程的,主要用途是與用戶互動(dòng),以及操作DOM。為了避免兩個(gè)線程同時(shí)操作DOM的情況發(fā)生,就采用了單線程。即使H5提出了web worker標(biāo)準(zhǔn),它有很多限制,受主線程控制,是主線程的子線程。
-非阻塞
通過EventLoop實(shí)現(xiàn)

宏任務(wù)和微任務(wù)

宏任務(wù)和微任務(wù)
為什么要引入微任務(wù),只有一種類型的任務(wù)不行么?

頁面渲染事件,各種IO的完成事件等隨時(shí)被添加到任務(wù)隊(duì)列中,一直會(huì)保持先進(jìn)先出的原則執(zhí)行,我們不能準(zhǔn)確地控制這些事件被添加到任務(wù)隊(duì)列中的位置。但是這個(gè)時(shí)候突然有高優(yōu)先級的任務(wù)需要盡快執(zhí)行,那么一種類型的任務(wù)就不合適了,所以引入了微任務(wù)隊(duì)列。

瀏覽器里的事件循環(huán)

關(guān)于微任務(wù)和宏任務(wù)在瀏覽器的執(zhí)行順序是這樣的:

執(zhí)行一只task(宏任務(wù))
執(zhí)行完micro-task隊(duì)列 (微任務(wù))
如此循環(huán)往復(fù)下去

常見的 task(宏任務(wù)) 比如:setTimeout、setInterval、script(整體代碼)、 I/O 操作、UI 渲染等。
常見的 micro-task 比如: new Promise().then(回調(diào))、MutationObserver(html5新特性) 等。

Node里的事件循環(huán)

大體的task(宏任務(wù))執(zhí)行順序是這樣的:

timers定時(shí)器:本階段執(zhí)行已經(jīng)安排的 setTimeout() 和 setInterval() 的回調(diào)函數(shù)。
pending callbacks待定回調(diào):執(zhí)行延遲到下一個(gè)循環(huán)迭代的 I/O 回調(diào)。
idle, prepare:僅系統(tǒng)內(nèi)部使用。
poll 輪詢:檢索新的 I/O 事件;執(zhí)行與 I/O 相關(guān)的回調(diào)(幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),它們由計(jì)時(shí)器和 setImmediate() 排定的之外),其余情況 node 將在此處阻塞。
check 檢測:setImmediate() 回調(diào)函數(shù)在這里執(zhí)行。
close callbacks 關(guān)閉的回調(diào)函數(shù):一些準(zhǔn)備關(guān)閉的回調(diào)函數(shù),如:socket.on('close', ...)。

微任務(wù)和宏任務(wù)在Node的執(zhí)行順序

Node 10以前:
執(zhí)行完一個(gè)階段的所有任務(wù)
執(zhí)行完nextTick隊(duì)列里面的內(nèi)容
然后執(zhí)行完微任務(wù)隊(duì)列的內(nèi)容

Node 11以后:
和瀏覽器的行為統(tǒng)一了,都是每執(zhí)行一個(gè)宏任務(wù)就執(zhí)行完微任務(wù)隊(duì)列。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容