【问题标题】:Nodejs: How to handle event listening between objects?Nodejs:如何处理对象之间的事件监听?
【发布时间】:2012-12-10 20:06:03
【问题描述】:

我目前遇到的问题是我有一个对象应该监听另一个对象。

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

注册人:

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

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

【问题讨论】:

    标签: javascript node.js dom-events publish-subscribe commonjs


    【解决方案1】:

    这实际上取决于对象将如何广播和收听以及您要求它们如何耦合或解耦。一般来说,这种类型的事件架构的最佳用途是一个对象可以不加选择地向其他对象宣布事件,并且这些对象可以自行选择侦听(注册)或停止侦听(取消注册)。

    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);
      });
    };
    

    【讨论】:

      【解决方案2】:

      编辑

      根据您的评论,我不确定您对此有什么不明白的地方,但您可以尝试使用 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'
      

      【讨论】:

      • 嗨,实际上我已经使用了 EventEmitter(查看源代码)问题是如何以可读、灵活和干净的方式将侦听器添加到事件发射对象
      • 嗨,您认为流对于我在github.com/bodokaiser/documents/blob/eventdriven-collection/lib/… 中的用例来说是一个不错的决定吗?我虽然流只适用于二进制文件或真正的网络流?我更需要松散耦合的事件
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多