我想做这样的事情:
var events = require("events");
var emitterA = new events.EventEmitter();
var emitterB = new events.EventEmitter();
emitterA.addListener("testA", function(){
console.log("emitterA detected testA");
});
emitterB.addListener("testA", function(){
console.log("emitterB detected testA");
});
emitterA.emit("testA");
输出是这样的:
emitterA detected testA
emitterB detected testA
但是当我运行这段代码时,我得到的输出是:
emitterA detected testA
我基本上想要一个发射器来监听另一个发射器发出的事件.
理由:
我正在Node上编写服务器,服务器发送Server Sent Events.这意味着我需要持久连接.为了确保连接没有因某种原因而关闭(我不想将超时设置为无穷大,因为这感觉像是一个黑客并且看起来不安全),我发出一个只有空白数据的心跳,就这样了正在传递给浏览器.
我正在运行一个计时器,每个时间段(在我的测试用例中为1秒),它将触发server.emit(“hb”);之后我同时写入并向所有请求对象发送数据(在我的笔记本电脑上,这只是多个标签和多个浏览器).所以基本上是req.on(“hb”,回调)
对我来说,这似乎更清晰,因为替代方案是为每个请求对象提供自己的计时器,这意味着将有许多计时器在各处运行,每个计时器都会导致它们各自的请求对象发出心跳事件.这似乎是一种非理想的做事方式.
另外,因为每个请求对象都是自发创建和销毁的,所以这样做基本上可以确保创建和销毁侦听器.
所以我想要的是服务器发出的心跳事件,所有活动的请求对象都会听到它并沿着自己的连接写入数据.
另一个替代方案(我现在正在工作的那个)是让服务器监听它自己的事件,并让服务器写出心跳.这个问题是服务器上的maxListeners限制 – 每个请求对象都会向服务器追加一个新的“hb”监听器,以便服务器可以监听该特定请求对象的事件.但是,最大的听众是10,虽然我也可以将其设置为无限,但我并不太热衷于这样做,因为我真的好奇是否有更好的方法.
对我来说,最好和最干净的解决方案似乎是让请求对象“订阅”服务器事件.我这样做是为了学习如何在节点中编程,所以我想尽可能少地实现外部库并使用节点的原始功能来实现,但是如果它需要一个外部库,我会很乐意阅读它源代码,这样我就可以学习如何实现一个小的本地实现.
解决方法:
请注意,EventEmitters是javascript中的唯一来源.它们不是每个人都能听到的全系统事件.它们是可以发出事件以支持异步模式的对象.要完成你想要的,你需要多个东西来听同一个发射器.像这样的东西:
'use strict';
var events = require( 'events' );
//Create a new sole-source event emitter
var emitterA = new events.EventEmitter();
//create a container that can listen
function EventListener( name ) {
console.log( 'new event listener, name=' + name );
this.name = name;
this.ack = function() {
console.log( this.name + ' just heard testA' );
};
this.listenTo = function( event, emitter ) {
var self = this;
emitter.on( event, function() {
self.ack();
} );
};
}
var listenerA = new EventListener( 'A', emitterA );
listenerA.listenTo( 'testA', emitterA );
var listenerB = new EventListener( 'B', emitterA );
listenerB.listenTo( 'testA', emitterA );
setInterval( function() {
emitterA.emit( 'testA' );
}, 1000 );
输出:
$node testfile.js
new event listener, name=A
new event listener, name=B
A just heard testA
B just heard testA
A just heard testA
B just heard testA
...
请注意,对于其他用例,您将需要使用WebSockets. EventEmitters将无法以您希望的方式工作,尤其是远程客户端. (socket.io的评论确实是一个很好的起点.)