2012-07-26 19 views
1

下面的程序將掛在NodeJS中,有人知道爲什麼嗎?爲什麼'nextTick'在這裏表現不如預期?

 
ended = false; 

events = require('events'); 
eventEmitter = new events.EventEmitter(); 
eventEmitter.on('end', function() { 
    ended = true; 
}); 
setTimeout(function() { 
    eventEmitter.emit('end'); 
}, 100); 

while (!ended) { 
    process.nextTick(); 
} 

console.log('ended'); 

回答

4

nextTick是不是某種收益率的操作,它是調度回調,下一次發動機是可以這樣做的調用。這是「掛起」,因爲while循環的退出條件永遠不會滿足(並且永遠不會使用該代碼)。

2

簡短回答:因爲Node.JS是單線程的。

長答案:JavaScript被組織成一個持有事件的隊列。被解僱的這些事件在他們完成工作之前無法停止。也沒有其他代碼可以並行運行,因爲Node.JS 單線程。這意味着這個代碼:

while (!ended) { 
    process.nextTick(); 
} 

是一個無限循環。 ended變量永遠不會改變,因爲end處理程序在主事件(即您向我們顯示的代碼)完成其作業之前無法觸發。它永遠不會。

+1

JavaScript不是單線程的。大多數JavaScript *實現*實現它單線程,包括所有當前的瀏覽器(禁止使用[web workers](http://www.w3.org/TR/workers/))和V8,Node中的引擎(和鉻)。但是有多線程實現,包括Rhino(犀牛將JavaScript編譯爲JVM字節碼,並且JVM是多線程的)。 – 2012-07-26 13:55:36

+1

@ T.J.Crowder不夠公平。我已將其更改爲「Node.JS」。 – freakish 2012-07-26 13:57:32

1

process.nextTick();不會調用主循環的下一個週期,下一個週期自動出現,.nextTick()方法用來調用回調函數在下一個週期,信息:http://nodejs.org/api/process.html#process_process_nexttick_callback

while(!ended)是一個無限循環,這就是爲什麼應用程序掛起時,ended變量將不會改變,直到當前的週期並沒有結束,這是由while循環水淹沒。