From 706778a90247937af0af0ae668fabf03e142640b Mon Sep 17 00:00:00 2001 From: DavidCai Date: Fri, 29 Apr 2016 10:47:06 +0800 Subject: [PATCH] events: pass the original listener added by once When removing a `once` listener, the listener being passed to the `removeListener` callback is the wrapper. This unwraps the listener so that `removeListener` is passed the actual listener. PR-URL: https://github.com/nodejs/node/pull/6394 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- lib/events.js | 7 ++++--- test/parallel/test-event-emitter-remove-listeners.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/events.js b/lib/events.js index 04d13d4386..f0b323e15c 100644 --- a/lib/events.js +++ b/lib/events.js @@ -308,7 +308,7 @@ EventEmitter.prototype.prependOnceListener = // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function removeListener(type, listener) { - var list, events, position, i; + var list, events, position, i, originalListener; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); @@ -327,7 +327,7 @@ EventEmitter.prototype.removeListener = else { delete events[type]; if (events.removeListener) - this.emit('removeListener', type, listener); + this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; @@ -335,6 +335,7 @@ EventEmitter.prototype.removeListener = for (i = list.length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { + originalListener = list[i].listener; position = i; break; } @@ -356,7 +357,7 @@ EventEmitter.prototype.removeListener = } if (events.removeListener) - this.emit('removeListener', type, listener); + this.emit('removeListener', type, originalListener || listener); } return this; diff --git a/test/parallel/test-event-emitter-remove-listeners.js b/test/parallel/test-event-emitter-remove-listeners.js index ba25d9b8c1..309cf86be1 100644 --- a/test/parallel/test-event-emitter-remove-listeners.js +++ b/test/parallel/test-event-emitter-remove-listeners.js @@ -102,3 +102,14 @@ e6.emit('hello'); // Interal listener array [listener3] e6.emit('hello'); + +const e7 = new events.EventEmitter(); + +const listener5 = () => {}; + +e7.once('hello', listener5); +e7.on('removeListener', common.mustCall((eventName, listener) => { + assert.strictEqual(eventName, 'hello'); + assert.strictEqual(listener, listener5); +})); +e7.emit('hello');