以下是我的nodejs代码
var emitter = require('events'),
eventEmitter = new emitter.EventEmitter();
eventEmitter.on('data', function (result) { console.log('Im From Data'); });
eventEmitter.on('error', function (result) { console.log('Im Error'); });
require('http').createServer(function (req, res) {
res.end('Response');
var start = new Date().getTime();
eventEmitter.emit('data', true);
eventEmitter.emit('error', false);
while(new Date().getTime() - start < 5000) {
//Let me sleep
}
process.nextTick(function () {
console.log('This is event loop');
});
}).listen(8090);
Nodejs是单线程的,它在事件循环中运行,同一个线程为事件提供服务。 所以,在上面的代码请求我的localhost:8090节点线程应该保持忙于服务请求[睡眠5s]。
同时,eventEmitter会发出两个事件。因此,一旦请求被提供,这两个事件必须在事件循环中排队等待处理。
但事实并非如此,我可以看到事件在发出时同步提供。
这是预期的吗?我知道,如果它按预期工作,那么就不会使用扩展事件模块。但是eventEmitter发出的事件是如何处理的?
答案 0 :(得分:8)
只有需要异步处理的东西才会被推送到事件循环中。节点中的标准事件发射器将立即调度事件。只有使用process.nextTick
,setTimeout
,setInterval
或在C ++中明确添加的代码的代码才会影响事件循环,就像节点库一样。
例如,当您将节点的fs
库用于createReadStream
之类的内容时,它会返回一个流,但会在后台打开该文件。当它打开时,node添加到事件循环中,当循环中的函数被调用时,它将触发流对象上的'open'事件。然后,node将在后台从文件加载块,并添加到事件循环以触发流上的data
事件。
如果您希望在5秒后发出这些事件,则需要在忙碌循环后使用setTimeout
或发出emit
来电。
我也想明确一点,你应该永远不要像Node代码那样有一个繁忙的循环。我不知道你是不是只是为了测试事件循环,或者它是否是某些真实代码的一部分。如果您需要更多信息,请扩展您希望实现的功能。