diff --git a/doc/api/events.markdown b/doc/api/events.markdown index 7998684e739..10b9ed0441f 100644 --- a/doc/api/events.markdown +++ b/doc/api/events.markdown @@ -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 diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index b9f8291874f..d22795a4041 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -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; @@ -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); @@ -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; } diff --git a/lib/events.js b/lib/events.js index 223015ec602..69af3aee600 100644 --- a/lib/events.js +++ b/lib/events.js @@ -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; +}; diff --git a/lib/fs.js b/lib/fs.js index 1ad0b2e3ce9..d467c5e0cc1 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -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; } diff --git a/lib/http.js b/lib/http.js index 56d9aae4236..638cb0cb4bb 100644 --- a/lib/http.js +++ b/lib/http.js @@ -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 @@ -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. @@ -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(); diff --git a/lib/readline.js b/lib/readline.js index a2d7e1c8225..83b425c4df2 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -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 @@ -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) { @@ -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 { @@ -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); diff --git a/lib/stream.js b/lib/stream.js index 481d7644e5e..098ff613d27 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -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'); @@ -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) { @@ -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. } }