UNPKG

eventemitter4

Version:

EventEmitter4 is an alternative to node's built-in EventEmitter class, and to the existing alternatives EventEmitter2 and EventEmitter3

184 lines (148 loc) 6.09 kB
// EventEmitter4 // Written by Erik Poupaert, Cambodia // (c) 2014 // Licensed under the LGPL _=require('underscore'); /** * Constructor. Creates an emitter object. */ function Emitter() { if (!(this instanceof Emitter)) throw "this function must be called with the new operator"; this.init(); } /** * Initializes the emitter's data structure. * Is called by the constructor and must be called by any class that inherits from this one. */ Emitter.prototype.init=function(listener) { this.listeners={}; this.onceListeners={}; this.listenersToAnyEvent=[]; this.event=null; } Emitter.prototype.validateListener=function(listener) { if(!_.isFunction(listener)) throw new Error('listener is not a function'); }; /** * Registers a listener function for a particular event. * @param {string} event The event for which to register the listener function. * @param {function} listener The listener function to register. * @returns {void} nothing. */ Emitter.prototype.on=function(event,listener) { this.validateListener(listener); if(!_(this.listeners).has(event)) this.listeners[event]=[]; this.listeners[event].push(listener); }; /** * Registers a listener function for a particular event. The listener will be triggered at most once. * @param {string} event The event for which to register the listener function. * @param {function} listener The listener function to register. * @returns {void} nothing. */ Emitter.prototype.once=function(event,listener) { this.validateListener(listener); if(!_(this.onceListeners).has(event)) this.onceListeners[event]=[]; this.onceListeners[event].push(listener); }; /** * Registers a listener function for all events. * The listener can retrieve what event it was called for from the emitter.event variable * @param {function} listener The listener function to register. * @returns {void} nothing. */ Emitter.prototype.onAny=function(listener) { this.validateListener(listener); this.listenersToAnyEvent.push(listener); }; /** * Emits an event and triggers the listeners registered for this event. * function(event, [arg1, arg2, arg3, ...]) * @param {function} event The event to trigger. * @param {any} arg1,arg2,arg3,... Optional parameters that will be transmitted to the listener. As many parameters as needed can be transmitted. * @returns {void} nothing. */ Emitter.prototype.emit=function() { var args=_(arguments).toArray(); this.event=args.shift(); //notify the normal listeners if(_(this.listeners).has(this.event)) { this.listeners[this.event].forEach(function(listener){ listener.apply(this,args); }); } //notify the once listeners if(_(this.onceListeners).has(this.event)) { this.onceListeners[this.event].forEach(function(listener){ listener.apply(this,args); }); this.onceListeners=_(this.onceListeners).omit(this.event); } //notify the listeners to all events this.listenersToAnyEvent.forEach(function(listener){ listener.apply(this,args); }); this.event=null; }; /** * Removes a listener for a particular event. * @param {string} event The event for which to remove the listener function. * @param {function} listener The listener function to remove. * @returns {void} nothing. */ Emitter.prototype.removeListener=function(event,listener) { //remove from the listeners to all events this.listenersToAnyEvent=_(this.listenersToAnyEvent).without(listener); //remove from the normal listeners if(_(this.listeners).has(event)) { this.listeners[event]=_(this.listeners[event]).without(listener); //if there are no listeners left for the event, remove it if(this.listeners[event].length===0) this.listeners=_(this.listeners).omit(event); } //remove from the once listeners if(_(this.onceListeners).has(event)) { this.onceListeners[event]=_(this.onceListeners[event]).without(listener); //if there are no listeners left for the event, remove it if(this.onceListeners[event].length===0) this.onceListeners=_(this.onceListeners).omit(event); } } /** * Removes a listener for a particular event or from all events * @param {string} [event] The event for which to remove the listener function. If left undefined, the listener will be removed for all events. * @returns {void} nothing. */ Emitter.prototype.removeAllListeners=function(event) { if(_.isUndefined(event)) { //reset all data structures this.init(); } else { //remove from the normal listeners if(_(this.listeners).has(event)) this.listeners=_(this.listeners).omit(event); //remove from the once listeners if(_(this.onceListeners).has(event)) this.onceListeners[event]=_(this.onceListeners).omit(event); } } Emitter.prototype.tableToString=function(table) { var clone=_(table).clone(); _(clone).each(function(listeners,key){ clone[key]=listeners.length; }) return JSON.stringify(clone); } /** * Dumps the current state of the emitter into string. * @returns {string} The current state of the emitter. */ Emitter.prototype.toString=function() { return '{"listeners":'+this.tableToString(this.listeners)+",\n"+ '"onceListeners":'+this.tableToString(this.onceListeners)+",\n"+ '"listenersToAnyEvent":'+this.listenersToAnyEvent.length+'}'; } module.exports=Emitter;