NodeJS的Event Loop

NodeJS的Event Loop是用Libuv實現(xiàn)的。核心驅(qū)動為uv_run函數(shù),使用的是UV_RUN_ONCE模式,盡可能在一次uv_run周期中處理I/O的回調(diào)。(loop alive會判斷有沒有進(jìn)行中的異步請求。)

uv_run運行周期

NodeJS的一次Event Loop周期會經(jīng)歷N個階段,每個階段結(jié)束后會進(jìn)入下個階段。來自官方NodeJS文檔。

   ┌───────────────────────┐
┌─>│        timers         │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<─────┤  connections, │
│  └──────────┬────────────┘      │   data, etc.  │
│  ┌──────────┴────────────┐      └───────────────┘
│  │        check          │
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │
   └───────────────────────┘

timer:處理就緒的timer 回調(diào)隊列。(setTimeout或setInterval的callback)
I/O:處理就緒的I/O 回調(diào)隊列。(對應(yīng)uv_run的pending階段)
idle,prepare:處理就緒的internal 回調(diào)隊列。
poll:處理就緒的I/O 回調(diào)隊列或阻塞。
check:處理就緒的check 回調(diào)隊列。(setImmediate的callback)
close:處理就緒的句柄關(guān)閉回調(diào)。(資源回收時設(shè)定的close 回調(diào))

當(dāng)一個階段將當(dāng)前屬于自己的回調(diào)隊列處理完畢就會進(jìn)入下一個階段。所謂的“就緒”,是指進(jìn)入這個【階段前】就已經(jīng)完成異步請求準(zhǔn)備觸發(fā)的回調(diào)。

poll階段比較特殊,他有可能阻塞Node的線程。
如果在當(dāng)前Event Loop周期有過I/O回調(diào)事件的產(chǎn)生,又或是其他階段有異步回調(diào)可以處理,那么poll階段就不會阻塞。
如果沒有,Node的線程就會在這階段休眠,等待I/O或timer回調(diào)事件的產(chǎn)生。

poll階段的阻塞作用在于沒有可執(zhí)行的異步事件時,就此休眠線程,避免忙輪詢。(查資料很容易得知,poll階段內(nèi)核是選擇各個平臺最好的實現(xiàn)。然而,似乎為了統(tǒng)一在各個平臺的Event Loop,這個階段只會被I/O回調(diào)事件喚醒或超時結(jié)束。)

Event Loop在選擇低耗能的阻塞線程前,會盡可能地完成一次Loop周期,這樣的行為正好說明了它非常注重每種異步回調(diào)的實時性。至于為什么要劃分如此多的隊列和階段就不得而知了。

實際上,在一次Event Loop的close階段后,還會進(jìn)行一次timer回調(diào)隊列的處理。因為有poll階段的阻塞耗時,這時很可能有超時的回調(diào)可以執(zhí)行。

值得一提的是,process.nextTick和Promise事件會往microTask隊列加入回調(diào),而microTask會在每個階段結(jié)束時清空,這時Event Loop才進(jìn)入下一個階段。

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

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

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