Nodejs事件处理

时间:2012-05-17 14:14:52

标签: node.js eventemitter

以下是我的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发出的事件是如何处理的?

1 个答案:

答案 0 :(得分:8)

只有需要异步处理的东西才会被推送到事件循环中。节点中的标准事件发射器将立即调度事件。只有使用process.nextTicksetTimeoutsetInterval或在C ++中明确添加的代码的代码才会影响事件循环,就像节点库一样。

例如,当您将节点的fs库用于createReadStream之类的内容时,它会返回一个流,但会在后台打开该文件。当它打开时,node添加到事件循环中,当循环中的函数被调用时,它将触发流对象上的'open'事件。然后,node将在后台从文件加载块,并添加到事件循环以触发流上的data事件。

如果您希望在5秒后发出这些事件,则需要在忙碌循环后使用setTimeout或发出emit来电。

我也想明确一点,你应该永远不要像Node代码那样有一个繁忙的循环。我不知道你是不是只是为了测试事件循环,或者它是否是某些真实代码的一部分。如果您需要更多信息,请扩展您希望实现的功能。