Emitting an event within a `EventEmitter#once` callback of the same
event name will cause subsequent `EventEmitter#once` listeners of the
same name to be called multiple times.
var emitter = new EventEmitter();
emitter.once('e', function() {
emitter.emit('e');
console.log(1);
});
emitter.once('e', function() {
console.log(2);
});
emitter.emit('e');
// Output
// 2
// 1
// 2
Fix the issue, by calling the listener method only if it was not
already called.
if (typeof listener !== 'function')
throw TypeError('listener must be a function');
+ var fired = false;
+
function g() {
this.removeListener(type, g);
- listener.apply(this, arguments);
+
+ if (!fired) {
+ fired = true;
+ listener.apply(this, arguments);
+ }
}
g.listener = listener;
assert.equal(1, times_hello_emited);
});
+var times_recurse_emitted = 0;
+
+e.once('e', function() {
+ e.emit('e');
+ times_recurse_emitted++;
+});
+
+e.once('e', function() {
+ times_recurse_emitted++;
+});
+
+e.emit('e');
+
+process.on('exit', function() {
+ assert.equal(2, times_recurse_emitted);
+});