Browse Source

events: deprecate static listenerCount function

As per the discussion in #734, this patch deprecates the usage of
`EventEmitter.listenerCount` static function in the docs, and introduces
the `listenerCount` function in the prototype of `EventEmitter` itself.

PR-URL: https://github.com/nodejs/node/pull/2349
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
v4.0.0-rc
Sakthipriyan Vairamani 10 years ago
parent
commit
8f58fb92ff
  1. 3
      benchmark/events/ee-listener-count-on-prototype.js
  2. 7
      doc/api/events.markdown
  3. 2
      lib/_http_client.js
  4. 4
      lib/_http_server.js
  5. 4
      lib/_stream_readable.js
  6. 9
      lib/_tls_wrap.js
  7. 22
      lib/events.js
  8. 2
      lib/fs.js
  9. 8
      lib/readline.js
  10. 2
      lib/stream.js
  11. 3
      src/node.js
  12. 18
      test/parallel/test-event-emitter-listener-count.js
  13. 2
      test/parallel/test-event-emitter-subclass.js

3
benchmark/events/ee-listener-count.js → benchmark/events/ee-listener-count-on-prototype.js

@ -7,14 +7,13 @@ function main(conf) {
var n = conf.n | 0; var n = conf.n | 0;
var ee = new EventEmitter(); var ee = new EventEmitter();
var listenerCount = EventEmitter.listenerCount;
for (var k = 0; k < 10; k += 1) for (var k = 0; k < 10; k += 1)
ee.on('dummy', function() {}); ee.on('dummy', function() {});
bench.start(); bench.start();
for (var i = 0; i < n; i += 1) { for (var i = 0; i < n; i += 1) {
var r = listenerCount(ee, 'dummy'); var r = ee.listenerCount('dummy');
} }
bench.end(n); bench.end(n);
} }

7
doc/api/events.markdown

@ -137,10 +137,17 @@ Execute each of the listeners in order with the supplied arguments.
Returns `true` if event had listeners, `false` otherwise. Returns `true` if event had listeners, `false` otherwise.
### emitter.listenerCount(type)
* `type` {Value} The type of event
Returns the number of listeners listening to the `type` of event.
### Class Method: EventEmitter.listenerCount(emitter, event) ### Class Method: EventEmitter.listenerCount(emitter, event)
Return the number of listeners for a given event. Return the number of listeners for a given event.
_Note: This is deprecated. Use `emitter.listenerCount` instead._
### Event: 'newListener' ### Event: 'newListener'

2
lib/_http_client.js

@ -322,7 +322,7 @@ function socketOnData(d) {
var bodyHead = d.slice(bytesParsed, d.length); var bodyHead = d.slice(bytesParsed, d.length);
var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
if (EventEmitter.listenerCount(req, eventName) > 0) { if (req.listenerCount(eventName) > 0) {
req.upgradeOrConnect = true; req.upgradeOrConnect = true;
// detach the socket // detach the socket

4
lib/_http_server.js

@ -343,7 +343,7 @@ function connectionListener(socket) {
parser = null; parser = null;
var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
if (EventEmitter.listenerCount(self, eventName) > 0) { if (self.listenerCount(eventName) > 0) {
debug('SERVER have listener for %s', eventName); debug('SERVER have listener for %s', eventName);
var bodyHead = d.slice(bytesParsed, d.length); var bodyHead = d.slice(bytesParsed, d.length);
@ -467,7 +467,7 @@ function connectionListener(socket) {
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) && (req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
continueExpression.test(req.headers['expect'])) { continueExpression.test(req.headers['expect'])) {
res._expect_continue = true; res._expect_continue = true;
if (EventEmitter.listenerCount(self, 'checkContinue') > 0) { if (self.listenerCount('checkContinue') > 0) {
self.emit('checkContinue', req, res); self.emit('checkContinue', req, res);
} else { } else {
res.writeContinue(); res.writeContinue();

4
lib/_stream_readable.js

@ -533,7 +533,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
debug('onerror', er); debug('onerror', er);
unpipe(); unpipe();
dest.removeListener('error', onerror); dest.removeListener('error', onerror);
if (EE.listenerCount(dest, 'error') === 0) if (dest.listenerCount('error') === 0)
dest.emit('error', er); dest.emit('error', er);
} }
// This is a brutally ugly hack to make sure that our error handler // This is a brutally ugly hack to make sure that our error handler
@ -582,7 +582,7 @@ function pipeOnDrain(src) {
debug('pipeOnDrain', state.awaitDrain); debug('pipeOnDrain', state.awaitDrain);
if (state.awaitDrain) if (state.awaitDrain)
state.awaitDrain--; state.awaitDrain--;
if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { if (state.awaitDrain === 0 && src.listenerCount('data')) {
state.flowing = true; state.flowing = true;
flow(src); flow(src);
} }

9
lib/_tls_wrap.js

@ -5,7 +5,6 @@ const crypto = require('crypto');
const net = require('net'); const net = require('net');
const tls = require('tls'); const tls = require('tls');
const util = require('util'); const util = require('util');
const listenerCount = require('events').listenerCount;
const common = require('_tls_common'); const common = require('_tls_common');
const StreamWrap = require('_stream_wrap').StreamWrap; const StreamWrap = require('_stream_wrap').StreamWrap;
const Buffer = require('buffer').Buffer; const Buffer = require('buffer').Buffer;
@ -116,7 +115,7 @@ function requestOCSP(self, hello, ctx, cb) {
if (ctx.context) if (ctx.context)
ctx = ctx.context; ctx = ctx.context;
if (listenerCount(self.server, 'OCSPRequest') === 0) { if (self.server.listenerCount('OCSPRequest') === 0) {
return cb(null); return cb(null);
} else { } else {
self.server.emit('OCSPRequest', self.server.emit('OCSPRequest',
@ -396,11 +395,11 @@ TLSSocket.prototype._init = function(socket, wrap) {
ssl.handshakes = 0; ssl.handshakes = 0;
if (this.server) { if (this.server) {
if (listenerCount(this.server, 'resumeSession') > 0 || if (this.server.listenerCount('resumeSession') > 0 ||
listenerCount(this.server, 'newSession') > 0) { this.server.listenerCount('newSession') > 0) {
ssl.enableSessionCallbacks(); ssl.enableSessionCallbacks();
} }
if (listenerCount(this.server, 'OCSPRequest') > 0) if (this.server.listenerCount('OCSPRequest') > 0)
ssl.enableCertCb(); ssl.enableCertCb();
} }
} else { } else {

22
lib/events.js

@ -395,19 +395,23 @@ EventEmitter.prototype.listeners = function listeners(type) {
}; };
EventEmitter.listenerCount = function(emitter, type) { EventEmitter.listenerCount = function(emitter, type) {
var evlistener; return emitter.listenerCount(type);
var ret = 0; };
var events = emitter._events;
EventEmitter.prototype.listenerCount = function listenerCount(type) {
const events = this._events;
if (events) { if (events) {
evlistener = events[type]; const evlistener = events[type];
if (typeof evlistener === 'function')
ret = 1; if (typeof evlistener === 'function') {
else if (evlistener) return 1;
ret = evlistener.length; } else if (evlistener) {
return evlistener.length;
}
} }
return ret; return 0;
}; };
// About 1.5x faster than the two-arg version of Array#splice(). // About 1.5x faster than the two-arg version of Array#splice().

2
lib/fs.js

@ -1354,7 +1354,7 @@ fs.unwatchFile = function(filename, listener) {
stat.removeAllListeners('change'); stat.removeAllListeners('change');
} }
if (EventEmitter.listenerCount(stat, 'change') === 0) { if (stat.listenerCount('change') === 0) {
stat.stop(); stat.stop();
statWatchers.delete(filename); statWatchers.delete(filename);
} }

8
lib/readline.js

@ -683,7 +683,7 @@ Interface.prototype._ttyWrite = function(s, key) {
switch (key.name) { switch (key.name) {
case 'c': case 'c':
if (EventEmitter.listenerCount(this, 'SIGINT') > 0) { if (this.listenerCount('SIGINT') > 0) {
this.emit('SIGINT'); this.emit('SIGINT');
} else { } else {
// This readline instance is finished // This readline instance is finished
@ -746,7 +746,7 @@ Interface.prototype._ttyWrite = function(s, key) {
case 'z': case 'z':
if (process.platform == 'win32') break; if (process.platform == 'win32') break;
if (EventEmitter.listenerCount(this, 'SIGTSTP') > 0) { if (this.listenerCount('SIGTSTP') > 0) {
this.emit('SIGTSTP'); this.emit('SIGTSTP');
} else { } else {
process.once('SIGCONT', (function(self) { process.once('SIGCONT', (function(self) {
@ -907,7 +907,7 @@ function emitKeypressEvents(stream) {
stream[ESCAPE_DECODER].next(); stream[ESCAPE_DECODER].next();
function onData(b) { function onData(b) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) { if (stream.listenerCount('keypress') > 0) {
var r = stream[KEYPRESS_DECODER].write(b); var r = stream[KEYPRESS_DECODER].write(b);
if (r) { if (r) {
for (var i = 0; i < r.length; i++) { for (var i = 0; i < r.length; i++) {
@ -936,7 +936,7 @@ function emitKeypressEvents(stream) {
} }
} }
if (EventEmitter.listenerCount(stream, 'keypress') > 0) { if (stream.listenerCount('keypress') > 0) {
stream.on('data', onData); stream.on('data', onData);
} else { } else {
stream.on('newListener', onNewListener); stream.on('newListener', onNewListener);

2
lib/stream.js

@ -70,7 +70,7 @@ Stream.prototype.pipe = function(dest, options) {
// don't leave dangling pipes when there are errors. // don't leave dangling pipes when there are errors.
function onerror(er) { function onerror(er) {
cleanup(); cleanup();
if (EE.listenerCount(this, 'error') === 0) { if (this.listenerCount('error') === 0) {
throw er; // Unhandled stream error in pipe. throw er; // Unhandled stream error in pipe.
} }
} }

3
src/node.js

@ -802,8 +802,7 @@
}); });
process.on('removeListener', function(type, listener) { process.on('removeListener', function(type, listener) {
if (signalWraps.hasOwnProperty(type) && if (signalWraps.hasOwnProperty(type) && this.listenerCount(type) === 0) {
NativeModule.require('events').listenerCount(this, type) === 0) {
signalWraps[type].close(); signalWraps[type].close();
delete signalWraps[type]; delete signalWraps[type];
} }

18
test/parallel/test-event-emitter-listener-count.js

@ -0,0 +1,18 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const EventEmitter = require('events');
const emitter = new EventEmitter();
emitter.on('foo', function() {});
emitter.on('foo', function() {});
emitter.on('baz', function() {});
// Allow any type
emitter.on(123, function() {});
assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2);
assert.strictEqual(emitter.listenerCount('foo'), 2);
assert.strictEqual(emitter.listenerCount('bar'), 0);
assert.strictEqual(emitter.listenerCount('baz'), 1);
assert.strictEqual(emitter.listenerCount(123), 1);

2
test/parallel/test-event-emitter-subclass.js

@ -46,4 +46,4 @@ var ee2 = new MyEE2();
ee1.on('x', function() {}); ee1.on('x', function() {});
assert.equal(EventEmitter.listenerCount(ee2, 'x'), 0); assert.equal(ee2.listenerCount('x'), 0);

Loading…
Cancel
Save