Nodejs:如何处理对象之间的事件监听?

我目前有问题,我有一个对象,应该听另一个对象。

问题是:我应该如何处理订阅? 目前,我只知道两种可能的方式:

与注册人:

var Registrator = function() { this.listener = new Listener(); }; Registrator.prototype.register = function(subsriber) { var self = this; subscriber.on('event', function(info) { self.listener.doSomething(info); }); }; 

在构造函数中:

 var Subscriber = function() { var listener = require('./instanced-listener'); this.on('event', function(info) { listener.doSomething(info); }); }; 

正如你所看到的,两种方法都不是那么简洁。 还有另外一种模式可以用来解决这个问题吗?

问候

PS:

如果这个例子看起来太抽象了,这里是来源:

https://github.com/bodokaiser/documents/blob/master/lib/repository.js

检查构造函数,看看我的不快:)

这实际上取决于对象将如何广播和聆听,以及您需要如何耦合或分离。 一般而言,这种types的事件架构的最佳用途是对象可以随意地向其他对象公布事件,并且这些对象可以自行决定是select监听(注册)还是停止监听(取消注册)。

聆听者依赖于广播者

在某些情况下,让听众成为广播公司的依赖者是有道理的,在这种情况下,它将与广播公司所宣布的事件名称和事件的论据紧密相关。

 var Listener = function(broadcaster) { var self = this; broadcaster.on("event", function(info) { self.doSomething(info); }); }; 

还可以创build其他监听器类,并向同一个广播器注册自己。 广播者不了解听众,只有听众意识到这种关系。

2.广播员依靠听众

广播员只为听众宣布事件。 在这种情况下,事件架构可能是矫枉过正的,你可以用直接调用来replace事件。 你的第二个例子暗示了这一点,因为它与广播器的构造函数中的监听器是一对一的关系。

 var Broadcaster = function(listener) { this.doSomething = function() { // do something... listener.doSomething(info); }; }; 

这在广播者和听众的界面之间产生了强烈的耦合。 这种模式不像它可能首先出现的那样受到限制。 扩展这种模式的有用性的一种常见方法是用广播适配器replace基本的听众。 广播适配器与基本的侦听器相同,因为它携带相同的doSomething接口,但是实现了一个事件架构来将这个调用传递给其他对象。 这使广播公司变得非常简单,并以一个额外的课程为代价将事件外部化。

3.两者都是独立的

你的第一个例子是释放这个耦合的一个很好的例子,成本是一个额外的类。 中间阶层充当两个阶级之间的桥梁或适配器,因此既不依赖彼此的信息。 事件签名对监听器是隐藏的,监听器的方法签名对广播器是隐藏的。 通常,这种脱钩水平是不必要的,但它是一个重要的工具,应该意识到让两个class级相互隔离的重要性。

 var Bridge = function(listener, broadcaster) { broadcaster.on("event", function(info) { // if necessary translate the arguments as well listener.doSomething(info); }); }; 

编辑

根据你的评论,我不确定你觉得这个不可读,但你可以尝试使用Stream对象和优雅的Stream#pipe方法。

溪stream

 var Stream = require('stream').Stream; var util = require('util'); var Sender = function() { this.readable = true; this.saySomething = function(message) { this.emit('data', message); }; }; util.inherits(Sender, Stream); var Receiver = function() { this.writable = true; this.write = function(message) { console.log('received: ' + message); } }; util.inherits(Receiver, Stream); 

用法

 // instance of each var s = new Sender(); var r = new Receiver(); // connect using pipe! s.pipe(r); // an event s.saySomething('hello world'); //=> received: hello world 

我特别喜欢使用Stream对象。 pipe方法非常方便:)每个stream都有一个input和输出。 我喜欢他们,因为它鼓励你build立一个小的function组件,负责一个特定的任务。 然后,你可以链接/重用他们,但你觉得合适。


原帖

你会想使用EventEmitter

这是一个简单的例子

 var events = require('events'); var util = require('util'); var SampleEmitter = function() { events.EventEmitter.call(this); this.sayHello = function() { this.emit('hello', 'hello world'); }; }; util.inherits(SampleEmitter, events.EventEmitter); var SampleListener = function(emitter) { emitter.on('hello', function(data) { console.log(data); }); }; var se = new SampleEmitter(); var sl = new SampleListener(se); se.sayHello(); //=> 'hello world'