Browse Source

doc: update removeListener behaviour

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: nodejs/node#4759

PR-URL: https://github.com/nodejs/node/pull/5201

Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
process-exit-stdio-flushing
Vaibhav 9 years ago
committed by Benjamin Gruenbaum
parent
commit
f2bd9cddee
  1. 37
      doc/api/events.markdown
  2. 19
      test/parallel/test-event-emitter-remove-listeners.js

37
doc/api/events.markdown

@ -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 listener array for the specified `event`, then `removeListener` must be called
multiple times to remove each instance. 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 Because listeners are managed using an internal array, calling this will
change the position indices of any listener registered *after* the listener change the position indices of any listener registered *after* the listener
being removed. This will not impact the order in which listeners are called, being removed. This will not impact the order in which listeners are called,

19
test/parallel/test-event-emitter-remove-listeners.js

@ -83,3 +83,22 @@ e5.once('removeListener', common.mustCall(function(name, cb) {
})); }));
e5.removeListener('hello', listener1); e5.removeListener('hello', listener1);
assert.deepEqual([], e5.listeners('hello')); 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');

Loading…
Cancel
Save