簡體   English   中英

為什么以及何時使用 process.nextTick?

[英]Why and when to use process.nextTick?

下面是“practise01.js”文件中的代碼,

function fn(name){
   return f;

   function f(){
       var n = name;
       console.log("Next TICK "+n+", ");        
   }
}

function myTimeout(time,msg){
   setTimeout(function(){
       console.log("TIMEOUT "+msg);
   },time); 
}

process.nextTick(fn("ONE"));
myTimeout(500,"AFTER-ONE");
process.nextTick(fn("TWO"));
myTimeout(500,"AFTER-TWO");
process.nextTick(fn("THREE"));
myTimeout(500,"AFTER-THREE");
process.nextTick(fn("FOUR"));

運行上述代碼的輸出是

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise01.js                  

Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE

現在我在“practise02.js”中不使用process.nextTick寫了代碼,如下,

function myTimeout(time,msg){
  setTimeout(function(){
        console.log("TIMEOUT "+msg);
  },time);  
}

function fn(name){
  return f;

  function f(){
    var n = name;
    console.log("Next TICK "+n+", ");       
  }
}

fn("ONE")();
myTimeout(500,"AFTER-ONE");
fn("TWO")();
myTimeout(500,"AFTER-TWO");
fn("THREE")();
myTimeout(500,"AFTER-THREE");
fn("FOUR")();

運行上面的代碼后,輸出是

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js 
Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE

如果您看到兩個輸出相同。

那么在哪種情況下我需要使用 process.nextTick ?

當我嘗試閱讀更多內容時,我明白了如果我需要在事件循環為空時立即執行某個函數而不是執行“process.nextTick”。

那么它與我的第二種方法有何不同。

請解釋一下或給我一些指示

節點文檔實際上很好地解釋了何時以及為何使用 nextTick:

https://nodejs.org/api/process.html#process_process_nexttick_callback_args

它的作用:

這不是 setTimeout(fn, 0) 的簡單別名,它的效率更高。 它在事件循環的后續滴答中觸發任何其他 I/O 事件(包括計時器)之前運行。

以及何時使用:

這在開發 API 時很重要,以便讓用戶有機會在對象構建之后但在任何 I/O 發生之前分配事件處理程序......

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}
definitelyAsync(true, () => {
  foo();
});
bar(); // will now allways be called before foo()

您在帖子中找到了答案,您可以通過以下方式與我們分享您的輸出:

rahul@rahul:~/myPractise/PlainNodeJSPractise01/Process$ node practise02.js 
Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THRE

如果我們將您的超時間隔從 500 更改為 0,結果仍然相同:

 function fn(name){ return f; function f(){ var n = name; console.log("Next TICK "+n+", "); } } function myTimeout(time,msg){ setTimeout(function(){ console.log("TIMEOUT "+msg); },time); } process.nextTick(fn("ONE")); myTimeout(0,"AFTER-ONE");// set timeout to execute in 0 seconds for all process.nextTick(fn("TWO")); myTimeout(0,"AFTER-TWO"); process.nextTick(fn("THREE")); myTimeout(0,"AFTER-THREE"); process.nextTick(fn("FOUR"));

結果

Next TICK ONE, 
Next TICK TWO, 
Next TICK THREE, 
Next TICK FOUR, 
TIMEOUT AFTER-ONE
TIMEOUT AFTER-TWO
TIMEOUT AFTER-THREE

當您使用process.nextTick您基本上可以確保您作為參數傳遞的函數將在下一個滴答聲中立即被調用,即。 下一個事件循環的開始。這就是為什么下一個滴答中的所有函數都在計時器之前執行的原因,即。 setTimeout next tick 並不意味着下一秒,它意味着 nodejs eventloop 的下一個循環。 另外下一個刻度線確保您嘗試調用的函數是異步執行的。 並且下一個滴答比在事件循環中排隊等待執行的計時器、I/O 操作等具有更高的優先級。 當您想要確保您的代碼在下一個事件循環中而不是在指定時間之后執行時,您應該使用 nextTick。 nextTick 比計時器更有效,並且當您想確保您調用的函數異步執行時。 您可以在 nodejs 文檔中找到更多信息

首先讓我們了解 process.nextTick() 的行為

Eventloop 具有在每個階段執行不同類型的異步函數的階段。

process.nextTick(callback[, ...args])是 nodeJS 異步 API 的一部分。 但它在技術上不是事件循環的一部分。

nextTickQueue將在當前操作完成后處理,而不管事件循環的當前階段。

每當我們在事件循環的給定階段調用process.nextTick()時,傳遞給process.nextTick()回調將在事件循環繼續之前解決。

為什么我們需要使用process.nextTick

API 100% 同步或 100% 異步非常重要。 考慮這個例子:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}
const maybeTrue = Math.random() > 0.5;

maybeSync(maybeTrue, () => {
  foo();
});

bar();

目前尚不清楚是先調用foo()還是bar() 以下方法要好得多:

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

已經@Johannes Merz 在他的回答中提到了為什么使用process.nextTick(callback)而不是setTimeout(callback, 0)

有關更多信息,請參閱此處

暫無
暫無

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

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