Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ changes:
Type: Documentation-only

The [`events.listenerCount(emitter, eventName)`][] API is
deprecated. Please use [`emitter.listenerCount(eventName)`][] instead.
deprecated. Please use [`emitter.listenerCount(eventName, listener)`][] instead.
Comment thread
ShogunPanda marked this conversation as resolved.
Resolved

### DEP0034: `fs.exists(path, callback)`

Expand Down Expand Up @@ -3402,7 +3402,7 @@ be added when a function is bound to an `AsyncResource`.
[`dnsPromises.lookup()`]: dns.md#dnspromiseslookuphostname-options
[`domain`]: domain.md
[`ecdh.setPublicKey()`]: crypto.md#ecdhsetpublickeypublickey-encoding
[`emitter.listenerCount(eventName)`]: events.md#emitterlistenercounteventname
[`emitter.listenerCount(eventName, listener)`]: events.md#emitterlistenercounteventname-listener
Comment thread
ShogunPanda marked this conversation as resolved.
Resolved
[`events.listenerCount(emitter, eventName)`]: events.md#eventslistenercountemitter-eventname
[`fs.FileHandle`]: fs.md#class-filehandle
[`fs.access()`]: fs.md#fsaccesspath-mode-callback
Expand Down
13 changes: 10 additions & 3 deletions doc/api/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -646,16 +646,23 @@ Returns the current max listener value for the `EventEmitter` which is either
set by [`emitter.setMaxListeners(n)`][] or defaults to
[`events.defaultMaxListeners`][].

### `emitter.listenerCount(eventName)`
### `emitter.listenerCount(eventName[, listener])`

<!-- YAML
added: v3.2.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/46523
description: Added the listener argument.
Comment thread
ShogunPanda marked this conversation as resolved.
Resolved
-->

* `eventName` {string|symbol} The name of the event being listened for
* `listener` {Function} The event handler function
* Returns: {integer}

Returns the number of listeners listening to the event named `eventName`.
Returns the number of listeners listening for the event named `eventName`.
If `listener` is provided, it will return how many times the listener is found
in the list of the listeners of the event.

### `emitter.listeners(eventName)`

Expand Down Expand Up @@ -2468,7 +2475,7 @@ to the `EventTarget`.
[`EventTarget` error handling]: #eventtarget-error-handling
[`Event` Web API]: https://dom.spec.whatwg.org/#event
[`domain`]: domain.md
[`emitter.listenerCount()`]: #emitterlistenercounteventname
[`emitter.listenerCount()`]: #emitterlistenercounteventname-listener
[`emitter.removeListener()`]: #emitterremovelistenereventname-listener
[`emitter.setMaxListeners(n)`]: #emittersetmaxlistenersn
[`event.defaultPrevented`]: #eventdefaultprevented
Expand Down
19 changes: 18 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -832,17 +832,34 @@ EventEmitter.prototype.listenerCount = listenerCount;
* Returns the number of listeners listening to event name
* specified as `type`.
* @param {string | symbol} type
* @param {Function} listener
* @returns {number}
*/
function listenerCount(type) {
function listenerCount(type, listener) {
const events = this._events;

if (events !== undefined) {
const evlistener = events[type];

if (typeof evlistener === 'function') {
if (listener) {
Comment thread
ShogunPanda marked this conversation as resolved.
Resolved
return listener === evlistener ? 1 : 0;
}

return 1;
} else if (evlistener !== undefined) {
if (listener) {
Comment thread
ShogunPanda marked this conversation as resolved.
Resolved
let matching = 0;

for (let i = 0, l = evlistener.length; i < l; i++) {
if (evlistener[i] === listener || evlistener[i].listener === listener) {
matching++;
}
}

return matching;
}

return evlistener.length;
}
}
Expand Down
53 changes: 53 additions & 0 deletions test/parallel/test-events-listener-count-with-listener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

const common = require('../common');
const EventEmitter = require('events');
const assert = require('assert');

const EE = new EventEmitter();
const handler = common.mustCall(undefined, 3);
const anotherHandler = common.mustCall();

assert.strictEqual(EE.listenerCount('event'), 0);
assert.strictEqual(EE.listenerCount('event', handler), 0);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 0);

EE.on('event', handler);

assert.strictEqual(EE.listenerCount('event'), 1);
assert.strictEqual(EE.listenerCount('event', handler), 1);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 0);

EE.once('event', anotherHandler);

assert.strictEqual(EE.listenerCount('event'), 2);
assert.strictEqual(EE.listenerCount('event', handler), 1);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 1);

assert.strictEqual(EE.listenerCount('another-event'), 0);
assert.strictEqual(EE.listenerCount('another-event', handler), 0);
assert.strictEqual(EE.listenerCount('another-event', anotherHandler), 0);

EE.once('event', handler);

assert.strictEqual(EE.listenerCount('event'), 3);
assert.strictEqual(EE.listenerCount('event', handler), 2);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 1);

EE.emit('event');

assert.strictEqual(EE.listenerCount('event'), 1);
assert.strictEqual(EE.listenerCount('event', handler), 1);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 0);

EE.emit('event');

assert.strictEqual(EE.listenerCount('event'), 1);
assert.strictEqual(EE.listenerCount('event', handler), 1);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 0);

EE.off('event', handler);

assert.strictEqual(EE.listenerCount('event'), 0);
assert.strictEqual(EE.listenerCount('event', handler), 0);
assert.strictEqual(EE.listenerCount('event', anotherHandler), 0);