【问题标题】:Nodejs event handlingNodejs 事件处理
【发布时间】:2012-05-17 14:14:52
【问题描述】:

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

【问题讨论】:

  • 只是推测您报告的内容......似乎 eventEmitter.emit 是同步处理的(不是异步的)。这意味着它们永远不会在事件队列中排队... FWIW,这就是我一直在 java 中实现所有侦听器/事件模式的方式。所以这看起来似乎是正确的行为

标签: node.js eventemitter


【解决方案1】:

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

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

如果您希望这些事件在 5 秒后发出,您需要使用 setTimeout 或在繁忙循环之后调用 emit

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

【讨论】:

  • 我 100% 确定我不应该阻塞事件循环。这只是我为理解行为而编写的测试代码 :) 感谢您的解释 :) 您还可以详细说明 code explicitly adding it to in C++ 部分,以便我 100% 清楚并接受答案
猜你喜欢
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 2019-06-27
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多