Skip to content
This repository was archived by the owner on Aug 15, 2024. It is now read-only.

Commit 03baa8a

Browse files
committed
added removeListener event #6
1 parent de1a48b commit 03baa8a

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

lib/events.js

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,25 +164,69 @@ EventEmitter.prototype.removeListener = function(type, listener) {
164164
delete this._events[type];
165165
}
166166

167+
if (this._events.removeListener)
168+
this.emit('removeListener', type, listener);
167169
return this;
168170
};
169171

170172
EventEmitter.prototype.removeAllListeners = function(type) {
173+
var key, listeners;
174+
175+
if (!this._events)
176+
return this;
177+
178+
// not listening for removeListener, no need to emit
179+
if (!this._events.removeListener) {
180+
if (arguments.length === 0)
181+
this._events = {};
182+
else if (this._events[type])
183+
this._events[type] = undefined;
184+
return this;
185+
}
186+
187+
// emit removeListener for all listeners on all events
171188
if (arguments.length === 0) {
189+
for (key in this._events) {
190+
if (key === 'removeListener') continue;
191+
this.removeAllListeners(key);
192+
}
193+
this.removeAllListeners('removeListener');
172194
this._events = {};
173195
return this;
174196
}
175197

176-
// does not use listeners(), so no side effect of creating _events[type]
177-
if (type && this._events && this._events[type]) this._events[type] = null;
198+
listeners = this._events[type];
199+
200+
if (typeof listeners === 'function') {
201+
this.removeListener(type, listeners);
202+
} else {
203+
// LIFO order
204+
while (listeners.length)
205+
this.removeListener(type, listeners[listeners.length - 1]);
206+
}
207+
this._events[type] = undefined;
208+
178209
return this;
179210
};
180211

181212
EventEmitter.prototype.listeners = function(type) {
182-
if (!this._events) this._events = {};
183-
if (!this._events[type]) this._events[type] = [];
184-
if (!isArray(this._events[type])) {
185-
this._events[type] = [this._events[type]];
186-
}
187-
return this._events[type];
213+
var ret;
214+
if (!this._events || !this._events[type])
215+
ret = [];
216+
else if (typeof this._events[type] === 'function')
217+
ret = [this._events[type]];
218+
else
219+
ret = this._events[type].slice();
220+
return ret;
188221
};
222+
223+
EventEmitter.listenerCount = function(emitter, type) {
224+
var ret;
225+
if (!emitter._events || !emitter._events[type])
226+
ret = 0;
227+
else if (typeof emitter._events[type] === 'function')
228+
ret = 1;
229+
else
230+
ret = emitter._events[type].length;
231+
return ret;
232+
};

test/events.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ test('remove all listeners', function() {
259259
assert.deepEqual([], e2.listeners('bar'));
260260
});
261261

262-
test('remove listener', function() {
262+
test('remove listener', function(done) {
263263
var count = 0;
264264

265265
function listener1() {
@@ -289,6 +289,24 @@ test('remove listener', function() {
289289
e3.on('hello', listener2);
290290
e3.removeListener('hello', listener1);
291291
assert.deepEqual([listener2], e3.listeners('hello'));
292+
293+
done = after(2, done);
294+
function remove1() {
295+
assert(0);
296+
}
297+
function remove2() {
298+
assert(0);
299+
}
300+
var e4 = new events.EventEmitter();
301+
e4.on('removeListener', function(name, cb) {
302+
if (cb !== remove1) return done();
303+
this.removeListener('quux', remove2);
304+
this.emit('quux');
305+
done();
306+
});
307+
e4.on('quux', remove1);
308+
e4.on('quux', remove2);
309+
e4.removeListener('quux', remove1);
292310
});
293311

294312
test('subclass', function(done) {

0 commit comments

Comments
 (0)