setTimeout和setImmediate以及process.nextTick的區別


  在javascript中我們了解到了setTimeout和setInterVal函數事件隊列(任務隊列)的相關知識,除了setTimeout和setInterval這兩個方法外,Node.js還提供了另外兩個與"任務隊列"有關的方法:process.nextTick和setImmediate。它們可以幫助我們加深對"任務隊列"的理解。

  setTimeout()

  首先我們看看setTimeout(setInterVal和setTimeout函數區別只是執行次數)函數,需要注意的是,setTimeout()只是將事件插入了"任務隊列",必須等到當前代碼(執行棧)執行完,主線程才會去執行它指定的回調函數。要是當前代碼耗時很長,有可能要等很久,所以並沒有辦法保證,回調函數一定會在setTimeout()指定的時間執行。

1 setTimeout(function(){console.log('0')},0);//意思是回調函數加入事件隊列的隊尾,主線程和事件隊列的函數執行完成之后立即執行定時器的回調函數,如果定時器的定時是相同的,就按定時器回調函數的先后順序來執行。
2 console.log(1);
3 setTimeout(function(){console.log(2);},1000);
4 setTimeout(function(){console.log(4);},1000);
5 console.log(3);
6 //1 3 0 2 4

  setImmediate()

  setImmediate()是將事件插入到事件隊列尾部,主線程和事件隊列的函數執行完成之后立即執行setImmediate指定的回調函數,和setTimeout(fn,0)的效果差不多,但是當他們同時在同一個事件循環中時,執行順序是不定的。另外setTimeout和setImmediate也有一定的區別(還在探索...),在實際工作中我們其實她們的區別貌似不明顯,請高手指出感激不盡

 1 console.log('1');
 2 
 3 setImmediate(function () {
 4     console.log('2');
 5 });
 6 
 7 setTimeout(function () {
 8    console.log('3');
 9 },0);
10 
11 process.nextTick(function () {
12     console.log('4');
13 });
14 
15 //1 4 2 3也可能是1 4 3 2

 

  process.nextTick()

  process.nextTick()方法可以在當前"執行棧"的尾部-->下一次Event Loop(主線程讀取"任務隊列")之前-->觸發process指定的回調函數。也就是說,它指定的任務總是發生在所有異步任務之前,當前主線程的末尾。(nextTick雖然也會異步執行,但是不會給其他io事件執行的任何機會)

 1 process.nextTick(function A() {
 2   console.log(1);
 3   process.nextTick(function B(){console.log(2);});
 4 });
 5 
 6 setTimeout(function C() {
 7   console.log(3');
 8 }, 0)
 9 // 1
10 // 2
11 // 3

當然這樣也是一樣的:

setTimeout(function C() {
    console.log(3');
}, 0)
process.nextTick(function A() {
    console.log(1);
    process.nextTick(function B(){console.log(2);});
});
// 1
// 2
// 3

當然這樣還是一樣的:

setTimeout(function C() {
    console.log(3');
}, 0)
process.nextTick(function A() {
    process.nextTick(function B(){console.log(2);});
    console.log(1);
});
// 1
// 2
// 3

 最后process.maxTickDepth()的缺省值是1000,如果超過會報exceed callback stack。官方認為在遞歸中用process.nextTick會造成飢餓event loop,因為nextTick沒有給其他異步事件執行的機會,遞歸中推薦用setImmediate

foo = function(bar) {
    console.log(bar);
    return process.nextTick(function() {
                return f(bar + 1);
    });
};
setImmediate(function () {
      console.log('1001');
});
foo(1);//注意這樣不會輸出1001,當遞歸執行到1000次是就會報錯exceed callback stack,
/*
foo = function(bar) {
    console.log(bar);
   if(bar>1000){
return;
} return process.nextTick(function() { return f(bar + 1); }); }; setImmediate(function () { console.log('1001'); }); foo(1);
*/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM