From: Arnout Kazemier Date: Fri, 18 Mar 2011 20:02:14 +0000 (+0100) Subject: Added support for removing .once listeners X-Git-Tag: v0.4.4~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=53bec1c8625c38888a15f7eb278cc19a212c154a;p=platform%2Fupstream%2Fnodejs.git Added support for removing .once listeners Closes GH-806. --- diff --git a/lib/events.js b/lib/events.js index 2d2d5d1..6fe55bb 100644 --- a/lib/events.js +++ b/lib/events.js @@ -138,10 +138,13 @@ EventEmitter.prototype.on = EventEmitter.prototype.addListener; 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; }; @@ -157,12 +160,23 @@ EventEmitter.prototype.removeListener = function(type, listener) { 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]; } diff --git a/test/simple/test-event-emitter-once.js b/test/simple/test-event-emitter-once.js index fb17237..55f0f16 100644 --- a/test/simple/test-event-emitter-once.js +++ b/test/simple/test-event-emitter-once.js @@ -35,6 +35,14 @@ e.emit('hello', 'a', 'b'); 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); });