EventEmitter.prototype.once = function(type, listener) {
var self = this;
- self.on(type, function g() {
+ function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
- });
+ };
+
+ g.listener = listener;
+ self.on(type, g);
return this;
};
var list = this._events[type];
if (isArray(list)) {
- var i = list.indexOf(listener);
- if (i < 0) return this;
- list.splice(i, 1);
+ var position = -1;
+ for (var i = 0, length = list.length; i < length; i++) {
+ if (list[i] === listener ||
+ (list[i].listener && list[i].listener === listener))
+ {
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0) return this;
+ list.splice(position, 1);
if (list.length == 0)
delete this._events[type];
- } else if (this._events[type] === listener) {
+ } else if (list === listener ||
+ (list.listener && list.listener === listener))
+ {
delete this._events[type];
}
e.emit('hello', 'a', 'b');
e.emit('hello', 'a', 'b');
+var remove = function() {
+ assert.fail(1,0, 'once->foo should not be emitted', '!');
+};
+
+e.once('foo', remove);
+e.removeListener('foo', remove);
+e.emit('foo');
+
process.addListener('exit', function() {
assert.equal(1, times_hello_emited);
});