4

以下是我的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 节点的请求的代码中,节点线程应该一直忙于为请求提供服务[有 5 秒的睡眠]。

同时有两个事件被 eventEmitter 发出。因此,一旦请求得到处理,这两个事件都必须在事件循环中排队等待处理。

但这并没有发生,我可以看到事件在发出时被同步服务。

这是预期的吗?我知道如果它按我的预期工作,那么扩展事件模块就没有用了。但是 eventEmitter 发出的事件是如何处理的呢?

4

1 回答 1

8

只有需要异步处理的东西才会被推送到事件循环中。node 中的标准事件发射器将立即分派一个事件。只有使用process.nextTick, setTimeout,之类setInterval的代码或在 C++ 中显式添加的代码会影响事件循环,例如节点的库。

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

如果您希望这些事件在 5 秒后发出,您可能希望在忙碌循环之后使用setTimeoutemit发出呼叫。

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

于 2012-05-17T15:28:40.063 回答