簡體   English   中英

在 Node.js 中,setImmediate() 回調在當前事件循環節拍或下一個節拍上執行?

[英]In Node.js, setImmediate() callbacks get executed on current event loop tick, or on the next one?

在官方文檔“setImmediate() vs setTimeout()”部分中,它說:“setImmediate() 旨在在當前輪詢階段完成后執行腳本”,據我了解,這也意味着當前的滴答/事件循環循環。

然而,稍后在“process.nextTick() vs setImmediate()”部分中,它說:“setImmediate() 在事件循環的后續迭代或‘tick’上觸發”。

那么哪個是正確答案,我在這里錯過了什么嗎?

提前致謝。

文檔相關頁面: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

感謝您加入 Stack Overflow!,我必須說您的問題非常好!


如下圖所示: 事件循環圈

該圖來自事件循環和大圖 — NodeJS 事件循環第 1 部分 作者 Deepal Jayasekara

“圓圈周圍的方框說明了我們之前看到的不同階段的隊列,中間的兩個方框說明了從一個階段移動到另一個階段之前需要耗盡的兩個特殊隊列。“下一個滴答隊列”處理回調通過 nextTick() 注冊,...”

來自Synk - Node.js Event-Loop:即使是快速的 Node.js 異步函數也能阻塞 Event-Loop,餓死 I/O參考上面的文章


所以setTimeoutsetImmediatenextTick之間的區別是:

  • setTimeout安排腳本在以毫秒為單位的最小閾值過去后運行。 1
  • setImmediate在 poll 階段之后運行(pool 階段是圖中的 IO 事件隊列)
  • nextTick在階段之間運行。

1定時器的執行順序將根據調用它們的上下文而有所不同,請參閱此處了解更多信息

setImmediatesetTimeout都在事件循環的不同階段運行。

這就是為什么當setTimeout設置為零延遲時,它不會立即運行。 使用始終在事件循環的下一個滴答上運行的 setImmediate。

但是process.nextTick基本上不關心事件循環的階段。 您分配給此方法的回調將在當前操作完成后和事件循環繼續之前執行。

作為 JS 工程師,tick 的概念是 scope 中的 IMO,因為我們沒有本地 API 來查找或計算我們現在處於哪個 tick。 有時,輪詢階段會等待傳入的請求完成,並且事件循環會停留在同一時刻。 但是,我們確實可以嘗試通過適當的代碼示例來理解這個概念。

我在官方 node.js 開發文檔上問了同樣的問題,他們還沒有回復我https://github.com/nodejs/nodejs.dev/issues/2343

根據我運行和觀察的代碼,文檔並沒有真正清楚地解釋它。 但這里是這樣的:

  • setImmediate 在主模塊中事件循環的下一個滴答時運行。 例如:來自 index.js/main.js 的初始代碼。
// Both of the codes will be executed in the next tick of the event loop.
// Depending on the event-loop start time, if the timer is executed in the next tick, then setImmediate will also do the same, as the check-phase follows the timers phase.
// If the timer is delayed further then only setImmediate will be executed in the next tick and the timer a tick after that.

setTimeout(() => console.log('May be I run first'), 0);
setImmediate(() => console.log('May be I run first'));
 
 
  • setImmediate 在 I/O 回調內的事件循環的同一迭代上運行。 因為定時器回調總是在 setImmediate 回調之后執行。
  fs.read('/file/path', () => {

    // check phase follows the I/O phase and poll phase. 
    // And when the poll phase is idle then the check phase is run right after.
    setImmediate(() => console.log('I am printed first always'));

    // Timers will be deferred to the next tick as timers-phase are the start of a "tick".
    setTimeout(() => console.log('I will be called in the next tick'), 0);
   
    setTimeout(() => console.log('I will be called may be tick after next one'), 100);
    

  }); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM