2015-09-25 118 views
1

據我瞭解,process.nextTick()setImmediate()之間的區別是如下:由process.nextTick()計劃都將進入下一個事件循環之前執行node.js的setImmediate意外行爲

  1. 回調,而回調定於setImmediate()會每個事件循環只能執行一次。
  2. 根據上述特點,可以這樣說:遞歸調用process.nextTick()會導致程序掛起,而遞歸調用setImmediate()則不會。

然後,我已經寫了一些測試代碼來驗證上面的語句,這裏是我的代碼:

process.nextTick(function() { 
    console.log('nextTick1'); 
}); 

process.nextTick(function() { 
    console.log('nextTick2'); 
}); 

setImmediate(function() { 
    console.log('setImmediate1'); 
    process.nextTick(function() { 
     console.log('nextTick3'); 
    }); 
}); 

setImmediate(function() { 
    console.log('setImmediate2'); 
}); 

我預期的結果應該是

nextTick1,nextTick2,setImmediate1,nextTick3 ,setImmediate2

,但我實際得到的是

nextTick1,nextTick2,setImmediate1,setImmedate2,nextTick3

然後我碰到另一個測試,以研究setImmediate()行爲:

//the following code is using express as the framework 
app.get('/test', function (req, res) { 
    res.end('The server is responding.'); 
}); 

app.get('/nexttick', function (req, res) { 
    function callback() { 
     process.nextTick(callback); 
    } 
    callback(); 
    res.end('nextTick'); 
}); 

app.get('/setimmediate', function (req, res) { 
    function callback() { 
     setImmediate(callback); 
    } 
    callback(); 
    res.end('setImmediate'); 
}); 

第一步:我在我的瀏覽器訪問http://localhost:3000/nexttick和我收到了文字nexttick

第2步:我訪問了http://localhost:3000/test來測試我的服務器是否仍然響應請求,並且我沒有得到任何響應,瀏覽器一直在等待響應。這並不奇怪,因爲遞歸調用process.nextTick()已經掛起了服務器。

第3步:我重新啓動了我的服務器。

第四步:我訪問http://localhost:3000/setimmediate,並得到了文本setimmediate

第五步:我再次訪問http://localhost:3000/test來測試我的服務器仍在運行。結果和Step2一樣,我沒有收到任何迴應,瀏覽器一直在等待迴應。

這意味着process.nextTick()setImmediate()的行爲幾乎相同,但我知道它們不是。

我想知道爲什麼會發生這種情況,或者我誤解了某事。謝謝。

P.S.我在Windows 10下運行Node v0.12.7。

回答

0

其實你的測試結果看起來不錯(我只是指第一個測試)。 您的意見「setImmediate()只會在每個事件循環中執行一次。」是錯誤的,請參閱https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg 這就是您不理解第一個測試結果的原因。

基本上process.nextTick會把你的函數放在當前事件循環的結尾,而setImmediate會把它放到下一個事件循環中。

但是執行多個setImmediate是可以的,他們將全部進入下一個相同的事件循環。

setImmediate(function() { 
    console.log('setImmediate1'); 
    process.nextTick(function() { 
     console.log('nextTick3'); 
    }); 
}); 

setImmediate(function() { 
    console.log('setImmediate2'); 
}); 

基本上你已經把2功能sthat將在接下來的事件循環中調用,並在其中的一個,你把另外nextTick這將在同一週期的結束,而是在被調用同一週期結束。 因此,它將首先調用那些2 setImmediate和比第一個調用的nextTick。