Skip to content

Commit

Permalink
events: add check for listeners length
Browse files Browse the repository at this point in the history
Ability to return just the length of listeners for a given type, using
EventEmitter.listenerCount(emitter, event). This will be a lot cheaper
than creating a copy of the listeners array just to check its length.
  • Loading branch information
trevnorris authored and isaacs committed Mar 2, 2013
1 parent 7707acd commit 75305f3
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
6 changes: 6 additions & 0 deletions doc/api/events.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ Returns an array of listeners for the specified event.

Execute each of the listeners in order with the supplied arguments.


### Class Method: EventEmitter.listenerCount(emitter, event)

Return the number of listeners for a given event.


### Event: 'newListener'

* `event` {String} The event name
Expand Down
5 changes: 3 additions & 2 deletions lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
module.exports = Readable;
Readable.ReadableState = ReadableState;

var EE = require('events').EventEmitter;
var Stream = require('stream');
var util = require('util');
var StringDecoder;
Expand Down Expand Up @@ -451,7 +452,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
// however, don't suppress the throwing behavior for this.
function onerror(er) {
unpipe();
if (dest.listeners('error').length === 0)
if (EE.listenerCount(dest, 'error') === 0)
dest.emit('error', er);
}
dest.once('error', onerror);
Expand Down Expand Up @@ -537,7 +538,7 @@ function flow(src) {
state.flowing = false;

// if there were data event listeners added, then switch to old mode.
if (src.listeners('data').length)
if (EE.listenerCount(src, 'data') > 0)
emitDataEvents(src);
return;
}
Expand Down
11 changes: 11 additions & 0 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,14 @@ EventEmitter.prototype.listeners = function(type) {
}
return this._events[type].slice(0);
};

EventEmitter.listenerCount = function(emitter, type) {
var ret;
if (!emitter._events || !emitter._events[type])
ret = 0;
else if (typeof emitter._events[type] === 'function')
ret = 1;
else
ret = emitter._events[type].length;
return ret;
};
2 changes: 1 addition & 1 deletion lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@ fs.unwatchFile = function(filename, listener) {
stat.removeAllListeners('change');
}

if (stat.listeners('change').length === 0) {
if (EventEmitter.listenerCount(stat, 'change') === 0) {
stat.stop();
statWatchers[filename] = undefined;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ function socketOnData(d, start, end) {
var bodyHead = d.slice(start + bytesParsed, end);

var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
if (req.listeners(eventName).length) {
if (EventEmitter.listenerCount(req, eventName) > 0) {
req.upgradeOrConnect = true;

// detach the socket
Expand Down Expand Up @@ -1874,7 +1874,7 @@ function connectionListener(socket) {
var bodyHead = d.slice(start + bytesParsed, end);

var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
if (self.listeners(eventName).length) {
if (EventEmitter.listenerCount(self, eventName) > 0) {
self.emit(eventName, req, req.socket, bodyHead);
} else {
// Got upgrade header or CONNECT method, but have no handler.
Expand Down Expand Up @@ -1958,7 +1958,7 @@ function connectionListener(socket) {
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
continueExpression.test(req.headers['expect'])) {
res._expect_continue = true;
if (self.listeners('checkContinue').length) {
if (EventEmitter.listenerCount(self, 'checkContinue') > 0) {
self.emit('checkContinue', req, res);
} else {
res.writeContinue();
Expand Down
8 changes: 4 additions & 4 deletions lib/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ Interface.prototype._ttyWrite = function(s, key) {

switch (key.name) {
case 'c':
if (this.listeners('SIGINT').length) {
if (EventEmitter.listenerCount(this, 'SIGINT') > 0) {
this.emit('SIGINT');
} else {
// This readline instance is finished
Expand Down Expand Up @@ -673,7 +673,7 @@ Interface.prototype._ttyWrite = function(s, key) {

case 'z':
if (process.platform == 'win32') break;
if (this.listeners('SIGTSTP').length) {
if (EventEmitter.listenerCount(this, 'SIGTSTP') > 0) {
this.emit('SIGTSTP');
} else {
process.once('SIGCONT', (function(self) {
Expand Down Expand Up @@ -829,7 +829,7 @@ function emitKeypressEvents(stream) {
stream._keypressDecoder = new StringDecoder('utf8');

function onData(b) {
if (stream.listeners('keypress').length > 0) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
var r = stream._keypressDecoder.write(b);
if (r) emitKey(stream, r);
} else {
Expand All @@ -846,7 +846,7 @@ function emitKeypressEvents(stream) {
}
}

if (stream.listeners('keypress').length > 0) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
stream.on('data', onData);
} else {
stream.on('newListener', onNewListener);
Expand Down
8 changes: 4 additions & 4 deletions lib/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@

module.exports = Stream;

var events = require('events');
var EE = require('events').EventEmitter;
var util = require('util');

util.inherits(Stream, events.EventEmitter);
util.inherits(Stream, EE);
Stream.Readable = require('_stream_readable');
Stream.Writable = require('_stream_writable');
Stream.Duplex = require('_stream_duplex');
Expand All @@ -40,7 +40,7 @@ Stream.Stream = Stream;
// part of this class) is overridden in the Readable class.

function Stream() {
events.EventEmitter.call(this);
EE.call(this);
}

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

0 comments on commit 75305f3

Please sign in to comment.