I suddenly realized that event emitter in NodeJS is usually like a static method in Java.. Example:
// 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();
This code would give output:
a = 2
b = 2
While I'm actually expecting:
a = 0
b = 0
I believe this is because of the line:
A.prototype = new events.EventEmitter;
and I think the "prototype" kind of definition would be used like "static" in Java.
In order to have per-object based event listener, I changed the above code to be:
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();
This would be per-object event listener, but I don't really think that is a good design/implementation because it breaks the chaining of EventEmitter. I.e., like code bellow:
// can chain another method of A after the on() method
a.on("event",functionCallback).anotherMethodOfA();
I'd like to ask, what's a proper implementation of the per-object event listener in NodeJS?
You can use addListener or on to attach listeners to your custom events. You won't need to chain calls on these methods. Of course you can inherit any object from EventEmitter and add emitting functionality to your object. You can inherit your object from an instance of EventEmitter. There's is function called inherit in the util library which does that for you.
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...