2017-04-07 69 views
1

在閱讀關於節點JS事件循環的文檔後,在https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/處。我試着運行這個代碼來了解更多:節點JS process.nextTick和setTimeout

//setTimeout 1 
setTimeout(function A(){ 
    console.log('timeout 1 called!!!'); 
    process.nextTick(function E(){ 
     console.log('tick called'); 
    }) 
}); 
//setTimeout 2 
setTimeout(function B(){ 
    console.log('timeout 2 called!!!'); 
}); 

而且結果是不可預知的,當我試圖多次運行這段代碼,有時結果是:

timeout 1 called!!! 
timeout 2 called!!! 
tick called 

但有時則可能是:

timeout 1 called!!! 
tick called 
timeout 2 called!!! 

按照我的理解,這是因爲事件循環完成的每個階段後process.nextTick運行的發生。

所以,如果調用堆棧已經完成,有有2個個案會發生:

  1. 的NodeJS API完整的決心的setTimeout 1,在事件循環和事件循環開始的計時階段添加功能的定時器隊列前NodeJS API完成解析setTimeout 2.這意味着函數E將添加到nextTickQueue,然後將函數B添加到定時器隊列=>函數A完成後,定時器隊列爲空(定時器階段完成)=> nextTickQueue調用=>結果爲:
timeout 1 called!!! 
tick called!!! 
timeout 2 called!!! 
  • 的NodeJS API完整的決心的setTimeout 1,在後事件循環和的NodeJS API完整的決心的setTimeout 2的定時器相加入功能A到定時器隊列,加入函數B到定時器隊列之前事件循環開始。因此,事件循環將執行定時器隊列中的所有回調函數以完成定時器階段,因此nextTickQueue將在超時1和超時2完成後解析。其結果是:
  • timeout 1 called!!! 
    timeout 2 called!!! 
    tick called!!! 
    

    我是理解對不對?你們能幫我澄清一下嗎? 謝謝:)。

    回答

    1

    據我瞭解,這是由於process.nextTick運行 事件循環的每個階段完成後發生的。

    process.nextTick在每個階段結束之前和下一個開始之前執行。

    輸出是非確定性。您無法保證上述執行順序。你所能做的就是基於它的輸出的理由。

    所以,如果調用堆棧已經完成,有有2個個案會發生:

    的NodeJS API完整的決心的setTimeout 1,添加功能的定時器 隊列事件循環和事件的計時器階段在NodeJS之前循環啓動 API完成解析setTimeout 2。這是平均函數E將被 加入nextTickQueue函數B之前功能的完整,定時器隊列空(定時器相完整) => nextTickQueue稱爲=>結果之後添加到定時器隊列=> 是:

    一旦你開始你的node.js處理事件循環開始。更合適的術語應該是event loop moves to the nextPhase before setTimeout2 resolves

    休息由於您使用的技術術語很少,您提出的所有理由都很好。但沒關係!