2012-05-17 26 views
4

以下是我的代码的NodeJS事件的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单线程的,它在一个事件循环运行,并在同一个线程服务的事件。 因此,在上面的代码中,对我的本地主机:8090节点线程的请求应该保持忙于为请求提供服务[有5秒的睡眠时间]。

同时有两个事件由eventEmitter发出。因此,这两个事件都必须在事件回调中排队等待请求处理完成。

但是,这并没有发生,我可以看到发出的同时发生的事件。

这是预期的吗?我明白,如果它按我期望的那样工作,那么就不会使用扩展事件模块。但eventEmitter发出的事件是如何处理的?

+0

只是猜测你正在报告什么...它似乎像eventEmitter.emit同步处理(而不是异步)。这意味着他们从来没有在事件队列中排队...... FWIW,这是我一直在java中实现所有监听器/事件模式的方式。所以这似乎是振振有词的正确行为 – ControlAltDel

回答

7

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

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

如果您希望在5秒后发出这些事件,您希望在忙循环后使用setTimeout或拨打emit

我还想说清楚,你不应该像Node代码那样有一个繁忙的循环。我不知道你是否只是在测试事件循环,或者它是否是一些真实代码的一部分。如果您需要更多信息,请详细说明您希望实现的功能。

+0

我100%确定我不应该阻止事件回复。这只是我写的一个测试代码,用于理解行为:)感谢您的解释:)还可以详细说明'将代码明确地添加到C++'部分,这样我就可以100%清楚并接受答案 – Tamil

+0

酷。我已经更新了我的答案。 – loganfsmyth