0

我突然意识到NodeJS中的事件发射器通常就像Java中的静态方法。示例:

// This illustrated that event listener is universal
function A(a){
  var that = this;
  this.a = a;
  this.cnt = 0;
  this.done = function(){
    this.emit("done");
  };
  this.say = function(){
    console.log(a + " = " + that.cnt);
  };
  this.inc = function(){
    that.cnt++;
  };
}
A.prototype = new events.EventEmitter;


var a = new A("a"),
    b = new A("b"),
    c = new A("c");

a.on("done",function(){a.inc()});
b.on("done",function(){b.inc()});
c.on("done",function(){c.inc()});


c.done();
c.done();
a.say();
b.say();

此代码将给出输出:

a = 2
b = 2

虽然我实际上期待:

a = 0
b = 0

我相信这是因为这条线:

A.prototype = new events.EventEmitter;

我认为“原型”类型的定义会像 Java 中的“静态”一样使用。

为了拥有基于每个对象的事件侦听器,我将上面的代码更改为:

function B(a){
  var that = this;
  this.evt = new events.EventEmitter;
  this.a = a;
  this.cnt = 0;
  this.done = function(){
    this.evt.emit("done");
  };
  this.say = function(){
    console.log(a + " = " + that.cnt);
  };
  this.inc = function(){
    that.cnt++;
  };
}

var a = new B("a"),
    b = new B("b"),
    c = new B("c");

a.evt.on("done",function(){a.inc()});
b.evt.on("done",function(){b.inc()});
c.evt.on("done",function(){c.inc()});

c.done();
c.done();
a.say();
b.say();

这将是每个对象的事件侦听器,但我并不认为这是一个好的设计/实现,因为它破坏了 EventEmitter 的链接。即,像下面的代码:

// can chain another method of A after the on() method
a.on("event",functionCallback).anotherMethodOfA();

我想问一下,NodeJS 中每个对象的事件监听器的正确实现是什么?

4

1 回答 1

0

您可以使用addListeneron将侦听器附加到您的自定义事件。您不需要对这些方法进行链式调用。当然,您可以继承任何对象EventEmitter并向您的对象添加发射功能。您可以从EventEmitter. 库中调用inherit了一个util函数来为你做这件事。

var util = require('util');
var eventEmitter = require('events').EventEmitter;

// Now create your constructor/object.
function MyObj(a, b) {
    this.a = a;
    this.b = b;
    .
    .
    .
}
util.inherits(MyObj,eventEmitter);

// Implement your methods and add the functionality you need.
MyObj.prototype.aMethod = function(arg) {
    .
    .
    .
    // Define how to emit events
    if (arg == 'A')
        this.emit('eventA', this.a);
    else if (arg == 'B')
        this.emit('eventB');

    // Return this for chaining method calls
    return this;
}

MyObj.prototype.anotherMethod = function() {
    // Add more functionality...
    .
    .
    .
    return this;
}

// Now instantiate the constructor and add listenters

var instanceOfMyObj = new MyObj('a parameter', 'another parameter');

instanceOfMyObj.on('eventA', function(a){
    // Handle the event
});

// Now chain calls..
instanceOfMyObj.aMethod('A').anotherMethod(); // This will trigger eventA...
于 2013-05-29T06:21:09.950 回答