Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c814c7e

Browse filesBrowse files
lpincaItalo A. Casas
authored andcommitted
events: do not keep arrays with a single listener
Use the remaining listener directly if the array of listeners has only one element after running `EventEmitter.prototype.removeListener()`. Advantages: - Better memory usage and better performance if no new listeners are added for the same event. Disadvantages: - A new array must be created if new listeners are added for the same event. PR-URL: #12043 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Ron Korving <ron@ronkorving.nl>
1 parent 8058bae commit c814c7e
Copy full SHA for c814c7e

File tree

Expand file treeCollapse file tree

2 files changed

+28
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+28
-7
lines changed
Open diff view settings
Collapse file

‎lib/events.js‎

Copy file name to clipboardExpand all lines: lib/events.js
+11-7Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ EventEmitter.prototype.removeListener =
344344
} else if (typeof list !== 'function') {
345345
position = -1;
346346

347-
for (i = list.length; i-- > 0;) {
347+
for (i = list.length - 1; i >= 0; i--) {
348348
if (list[i] === listener || list[i].listener === listener) {
349349
originalListener = list[i].listener;
350350
position = i;
@@ -356,7 +356,6 @@ EventEmitter.prototype.removeListener =
356356
return this;
357357

358358
if (list.length === 1) {
359-
list[0] = undefined;
360359
if (--this._eventsCount === 0) {
361360
this._events = new EventHandlers();
362361
return this;
@@ -365,8 +364,12 @@ EventEmitter.prototype.removeListener =
365364
}
366365
} else if (position === 0) {
367366
list.shift();
367+
if (list.length === 1)
368+
events[type] = list[0];
368369
} else {
369370
spliceOne(list, position);
371+
if (list.length === 1)
372+
events[type] = list[0];
370373
}
371374

372375
if (events.removeListener)
@@ -378,7 +381,7 @@ EventEmitter.prototype.removeListener =
378381

379382
EventEmitter.prototype.removeAllListeners =
380383
function removeAllListeners(type) {
381-
var listeners, events;
384+
var listeners, events, i;
382385

383386
events = this._events;
384387
if (!events)
@@ -401,7 +404,8 @@ EventEmitter.prototype.removeAllListeners =
401404
// emit removeListener for all listeners on all events
402405
if (arguments.length === 0) {
403406
var keys = Object.keys(events);
404-
for (var i = 0, key; i < keys.length; ++i) {
407+
var key;
408+
for (i = 0; i < keys.length; ++i) {
405409
key = keys[i];
406410
if (key === 'removeListener') continue;
407411
this.removeAllListeners(key);
@@ -418,9 +422,9 @@ EventEmitter.prototype.removeAllListeners =
418422
this.removeListener(type, listeners);
419423
} else if (listeners) {
420424
// LIFO order
421-
do {
422-
this.removeListener(type, listeners[listeners.length - 1]);
423-
} while (listeners[0]);
425+
for (i = listeners.length - 1; i >= 0; i--) {
426+
this.removeListener(type, listeners[i]);
427+
}
424428
}
425429

426430
return this;
Collapse file

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

Copy file name to clipboardExpand all lines: test/parallel/test-event-emitter-remove-listeners.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,20 @@ assert.throws(() => {
136136
const e = ee.removeListener('foo', listener);
137137
assert.strictEqual(e, ee);
138138
}
139+
140+
{
141+
const ee = new EventEmitter();
142+
143+
ee.on('foo', listener1);
144+
ee.on('foo', listener2);
145+
assert.deepStrictEqual(ee.listeners('foo'), [listener1, listener2]);
146+
147+
ee.removeListener('foo', listener1);
148+
assert.strictEqual(ee._events.foo, listener2);
149+
150+
ee.on('foo', listener1);
151+
assert.deepStrictEqual(ee.listeners('foo'), [listener2, listener1]);
152+
153+
ee.removeListener('foo', listener1);
154+
assert.strictEqual(ee._events.foo, listener2);
155+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.