Skip to content

Instantly share code, notes, and snippets.

@tommedema
Created May 21, 2012 19:07
Show Gist options
  • Save tommedema/2764018 to your computer and use it in GitHub Desktop.
Save tommedema/2764018 to your computer and use it in GitHub Desktop.
monkey patches eventemitter (2) with .onceall function, see test for usage
var EventEmitter2 = require('eventemitter2').EventEmitter2,
EEPatcher = require('../../src/util/eepatcher')(EventEmitter2),
util = require('util'),
should = require('should'),
emitter = new EventEmitter2({
wildcard: false
});
describe('eepatcher', function() {
describe('onceall', function() {
it('should exist', function() {
emitter.onceall.should.exist;
emitter.onceall.should.be.a('function');
});
it('should throw without a callback', function() {
(function() {
emitter.onceall('eventone', 'eventtwo');
}).should.throw();
});
it('should throw with only a callback', function() {
(function() {
emitter.onceall(function() {});
}).should.throw();
});
it('should function with one event', function(done) {
emitter.onceall('eventone', function() {
done();
});
emitter.emit('eventone');
});
it('should function with two events', function(done) {
var e1fired = false,
e2fired = false;
emitter.onceall('eventone', 'eventtwo', function() {
e1fired.should.be.true;
e2fired.should.be.true;
done();
});
emitter.emit('eventone');
e1fired = true;
emitter.emit('eventtwo');
e2fired = true;
});
it('should ignore invalid events', function(done) {
emitter.onceall('eventone', 500, 'eventtwo', function() {
done();
});
emitter.emit('eventone');
emitter.emit('eventtwo');
});
it('should ignore duplicate events', function(done) {
emitter.onceall('deventone', 'deventone', 'deventtwo', 'deventthree', function() {
done();
});
emitter.emit('deventone');
emitter.emit('deventtwo');
emitter.emit('deventthree');
});
it('should give arguments sequentially', function(done) {
var arg1 = "arg1",
arg2 = 100,
arg3 = "arg3",
arg4 = 20,
arg5 = null;
emitter.onceall('seqev1', 'seqev2', 'seqev3', function(_arg1, _arg2, _arg3, _arg4, _arg5) {
_arg1.should.eql(arg1);
_arg2.should.eql(arg2);
_arg3.should.eql(arg3);
_arg4.should.eql(arg4);
should.not.exist(_arg5);
done();
});
emitter.emit('seqev3', arg4, arg5);
emitter.emit('seqev1', arg1);
emitter.emit('seqev2', arg2, arg3);
});
});
});
module.exports = function(EventEmitter) {
//original object must be passed
if (!EventEmitter) throw new Error("you must pass the EventEmitter object");
/*
* Register for all given events and wait for them all to have emitted at least once.
*
* @param {String} Any amount of events to listen for.
* @param {Function} Callback to be called when all events emitted, callback arguments are passed in the same order as the events.
*
* Ignores non-string or duplicate arguments except for the last argument which should be a function.
*/
EventEmitter.prototype.onceall = function() {
if (arguments.length < 2) throw new Error('you must pass at least one event and callback');
var cb = arguments[arguments.length-1];
if (typeof(cb) !== 'function') throw new Error('you must pass a callback');
var emitter = this;
//keep track of events
var events = [],
eargs = {},
evl = 0,
evc = 0;
for (var i = 0, il = arguments.length; i < il - 1; i++) {
if (typeof(arguments[i]) !== 'string' || eargs[arguments[i]]) continue;
registerEvent(arguments[i]);
}
function registerEvent(event) {
evl++;
events.push(event);
eargs[event] = true;
emitter.once(event, function() {
eargs[event] = Array.prototype.slice.call(arguments);
process.nextTick(function() {
if (evl === ++evc) cb.apply(emitter, getArgs());
});
});
}
function getArgs() {
var args = [];
for (var i = 0; i < evl; i++) {
args = args.concat(eargs[events[i]]);
}
return args;
}
};
//this is just an untested draft, don't pay attention to it yet
EventEmitter.prototype.onall = function() {
var evargs = arguments,
cb = evargs[evargs.length-1],
emitter = this;
if (typeof(cb) !== 'function') throw new Error('onall must be passed a callback as last argument');
cb = function() {
cb.apply(emitter, arguments);
emitter.onceall(evargs);
};
emitter.onceall(evargs);
};
//allow chaining
return EventEmitter;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment