Skip to content

Commit

Permalink
events: pass the original listener added by once
Browse files Browse the repository at this point in the history
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: #6394
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
DavidCai1111 authored and Fishrock123 committed May 4, 2016
1 parent 9f23cb2 commit 2c92a1f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
7 changes: 4 additions & 3 deletions lib/events.js
Expand Up @@ -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');
Expand All @@ -327,14 +327,15 @@ 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;

for (i = list.length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
originalListener = list[i].listener;
position = i;
break;
}
Expand All @@ -356,7 +357,7 @@ EventEmitter.prototype.removeListener =
}

if (events.removeListener)
this.emit('removeListener', type, listener);
this.emit('removeListener', type, originalListener || listener);
}

return this;
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-event-emitter-remove-listeners.js
Expand Up @@ -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');

0 comments on commit 2c92a1f

Please sign in to comment.