Nodejs:如何处理对象之间的事件监听
Nodejs: How to handle event listening between objects?
我现在有一个问题,我有一个对象应该监听另一个对象。
问题是:我应该如何处理订阅?目前,我只知道两种可能的方法:
与registrator: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检查构造函数以查看我的不快:)
这实际上取决于对象如何广播和侦听以及您要求它们如何耦合或解耦。一般来说,这种类型的事件体系结构的最佳用途是一个对象可以不加选择地向其他对象宣布事件,而这些对象可以根据自己的判断选择侦听(注册)或停止侦听(取消注册)。
1。侦听器依赖于广播器
在某些情况下,使侦听器依赖于广播器可能是有意义的,在这种情况下,它将与该广播器宣布的事件名称和事件的参数强耦合。
var Listener = function(broadcaster) {
var self = this;
broadcaster.on("event", function(info) {
self.doSomething(info);
});
};
也可以创建其他侦听器类,并将它们自己注册到相同的广播器。广播方不知道侦听方的存在,只有侦听方知道这种关系。
2。广播器依赖于侦听器
广播器仅为侦听器宣布事件。在这种情况下,事件体系结构可能过于复杂,您可以用直接调用替换事件。第二个例子暗示了这一点,因为在广播器的构造函数中与侦听器是一对一的关系。
var Broadcaster = function(listener) {
this.doSomething = function() {
// do something...
listener.doSomething(info);
};
};
这会在广播器和侦听器接口之间创建强耦合。不过,这种模式并不像最初看起来那么有限。扩展此模式的有用性的一种常见方法是用广播适配器替换基本侦听器。广播适配器看起来与基本侦听器相同,因为它携带相同的doSomething
接口,但实现了将此调用传递给其他对象的事件体系结构。这使得广播器非常简单,并以额外的类为代价外部化与事件有关的任何事情。
3。两者都是独立的
你的第一个例子是释放这种耦合的一个很好的例子,代价是一个额外的类。中间类充当两个类之间的桥梁或适配器,因此两者都不依赖于彼此的信息。事件签名对侦听器隐藏,侦听器的方法签名对广播器隐藏。通常这种级别的解耦是不必要的,但它是一个重要的工具,可以让您意识到保持两个类彼此隔离的重要性。
var Bridge = function(listener, broadcaster) {
broadcaster.on("event", function(info) {
// if necessary translate the arguments as well
listener.doSomething(info);
});
};
编辑
根据你的评论,我不确定你觉得这个不太好读,但是你可以尝试使用Stream
对象和优雅的Stream#pipe
方法。
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
方法非常方便:)每个流都有一个输入和输出。我喜欢它们,因为它鼓励您构建负责特定任务的小型功能组件。然后,您可以链接/重用它们,只要您认为合适。
原始文章
你需要使用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'
- 全局变量和全局对象的属性之间有什么区别吗
- JavaScript中的函数和对象之间没有区别吗?
- 在控制器和数据对象之间同步数据
- Javascript-defineProperty和直接在对象上定义函数之间的区别
- XMLHttpRequest对象的open()和send()方法之间有什么区别
- Firefox插件SDK:在侧边栏和主脚本之间通信对象
- 如何将json文件中的数据提取到对象数组中,并在两个控制器之间共享
- Angular 2,在没有直接关系的两个组件之间共享一个对象
- 尝试在一个对象的值和一个对象数组之间进行匹配
- 在angularJS中使用模态窗口时,在控制器之间共享对象数组
- 快递之间的区别.路由器() vs 多个 express() 对象
- 节点模块对象范围:在所有函数之间共享一个对象
- 在不同数据选项之间循环迭代对象
- 在 JavaScript 中的对象内分配柯里函数时,这和 self 之间有什么区别吗?
- 不同对象之间的递归,并将它们唯一地组合在一起,不重复
- 两个对象之间的Javascript原型
- 什么's对象文字中带引号和不带引号的键之间的区别
- 只有一些带undercore.js的字段在对象数组之间求交集和等于
- 用户如何获取两个时间戳之间的对象
- 在window.onload之前/之后创建对象之间的区别