From eb50d19461b5a0a3c893c4a26f85d825b77c962a Mon Sep 17 00:00:00 2001 From: Paolo Insogna Date: Mon, 13 Feb 2023 09:44:59 +0000 Subject: [PATCH] events: add listener argument to listenerCount --- doc/api/events.md | 11 ++++- lib/events.js | 18 ++++++- ...est-events-listener-count-with-listener.js | 47 +++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-events-listener-count-with-listener.js diff --git a/doc/api/events.md b/doc/api/events.md index 5f64fa1dec2a7a..aa4c4518008f44 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -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])` * `eventName` {string|symbol} The name of the event being listened for +* `listener` {Function} The name of the listener * Returns: {integer} Returns the number of listeners listening to the event named `eventName`. +If `listener` is provided, it will return `1` if the listener is found +in the list of the listeners of the event, `0` otherwise. ### `emitter.listeners(eventName)` @@ -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 diff --git a/lib/events.js b/lib/events.js index 4ed193dfcb9b17..4879e53d78a13b 100644 --- a/lib/events.js +++ b/lib/events.js @@ -33,6 +33,7 @@ const { ErrorCaptureStackTrace, FunctionPrototypeBind, FunctionPrototypeCall, + Number, NumberMAX_SAFE_INTEGER, ObjectDefineProperty, ObjectDefineProperties, @@ -832,17 +833,32 @@ 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) { + return Number(listener === evlistener); + } + return 1; } else if (evlistener !== undefined) { + if (listener) { + for (let i = 0, l = evlistener.length; i < l; i++) { + if (evlistener[i] === listener || evlistener[i].listener === listener) { + return 1; + } + } + + return 0; + } + return evlistener.length; } } diff --git a/test/parallel/test-events-listener-count-with-listener.js b/test/parallel/test-events-listener-count-with-listener.js new file mode 100644 index 00000000000000..712cc3663a86d3 --- /dev/null +++ b/test/parallel/test-events-listener-count-with-listener.js @@ -0,0 +1,47 @@ +'use strict'; + +const common = require('../common'); +const EventEmitter = require('events'); +const assert = require('assert'); + +const EE = new EventEmitter(); +const handler = common.mustCall(undefined, 2); +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.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);