Skip to content

Commit

Permalink
doc: update removeListener behaviour
Browse files Browse the repository at this point in the history
This commit updates events doc to describe removeListener behaviour
when it is called within a listener. An example is added to make
it more evident.

A test is also incuded to make this behaviour consistent in future
releases.

Fixes: #4759

PR-URL: #5201

Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
  • Loading branch information
vaibhav93 authored and Myles Borins committed Mar 17, 2016
1 parent d5debfb commit 115a980
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
37 changes: 37 additions & 0 deletions doc/api/events.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,43 @@ listener array. If any single listener has been added multiple times to the
listener array for the specified `event`, then `removeListener` must be called
multiple times to remove each instance.

Note that once an event has been emitted, all listeners attached to it at the
time of emitting will be called in order. This implies that any `removeListener()`
or `removeAllListeners()` calls *after* emitting and *before* the last listener
finishes execution will not remove them from `emit()` in progress. Subsequent
events will behave as expected.

```js
const myEmitter = new MyEmitter();

var callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};

var callbackB = () => {
console.log('B');
};

myEmitter.on('event', callbackA);

myEmitter.on('event', callbackB);

// callbackA removes listener callbackB but it will still be called.
// Interal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B

// callbackB is now removed.
// Interal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// A

```

Because listeners are managed using an internal array, calling this will
change the position indices of any listener registered *after* the listener
being removed. This will not impact the order in which listeners are called,
Expand Down
19 changes: 19 additions & 0 deletions test/parallel/test-event-emitter-remove-listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,22 @@ e5.once('removeListener', common.mustCall(function(name, cb) {
}));
e5.removeListener('hello', listener1);
assert.deepEqual([], e5.listeners('hello'));

const e6 = new events.EventEmitter();

const listener3 = common.mustCall(() => {
e6.removeListener('hello', listener4);
}, 2);

const listener4 = common.mustCall(() => {}, 1);

e6.on('hello', listener3);
e6.on('hello', listener4);

// listener4 will still be called although it is removed by listener 3.
e6.emit('hello');
// This is so because the interal listener array at time of emit
// was [listener3,listener4]

// Interal listener array [listener3]
e6.emit('hello');

0 comments on commit 115a980

Please sign in to comment.