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>
This commit is contained in:
Sakthipriyan Vairamani 2015-08-12 00:01:50 +05:30
parent d98eed51f7
commit 8f58fb92ff
13 changed files with 56 additions and 30 deletions

View File

@ -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);
} }

View File

@ -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'

View File

@ -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

View File

@ -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();

View File

@ -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);
} }

View File

@ -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 {

View File

@ -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().

View File

@ -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);
} }

View File

@ -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);

View File

@ -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.
} }
} }

View File

@ -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];
} }

View File

@ -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);

View File

@ -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);