2012-07-26 41 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循环水淹没。