Created
May 28, 2018 15:11
-
-
Save jagretz/59e5e655a972882003315a2599c019b6 to your computer and use it in GitHub Desktop.
Custom EventEmitter for created for the purpose of learning and teaching others.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example on codepen https://codepen.io/jagretz/pen/aGeMoJ | |
// If you would like a production version, use complete, tested, performant, and | |
// well-supported version https://github.com/facebook/emitter | |
/** | |
* Subscribe to and control when events are emitted to subscribers. | |
*/ | |
class EventEmitter { | |
constructor() { | |
// k,v store of events to subscribers. | |
this.events = {}; | |
} | |
/** | |
* Register a function (handler) to invoke when the given event (name) is triggered. | |
* @param {string} name to give the event. | |
* @param {function} handler to invoke when events are emitted. | |
* @return {function} #unsubscribe | |
*/ | |
subscribe(name, handler) { | |
if (!this.events[name]) this.events[name] = []; | |
this.events[name].push(handler); | |
return this.unsubscribe.bind(this, name, handler); | |
} | |
/** | |
* Remove the handler from the list of subscribers. | |
* If the event has no more subscriptions the event is also removed from the list of events. | |
*/ | |
unsubscribe(name, handler) { | |
console.info(`unsubscribing from ${name}`); | |
this.events[name] = this.events[name].filter(fn => handler !== fn); | |
if (this.events[name].length <= 0) delete this.events[name]; | |
} | |
/** | |
* Identical to #subscribe except that execution only occurs once and immediately unsubscribes. | |
* This type of subscription is useful in cases when you only need some behavior to occur | |
* one time. | |
*/ | |
once(name, handler) { | |
/* set the "this" context to a variable to pass into the "once" subscription handler. | |
* this is necessary to invoke the unsubscription function when the handler is invoked. | |
*/ | |
const self = this; | |
/* creates a _new_ subscription handler to control both subscription and unsubscription logic. */ | |
function onceHandler(...args) { | |
self.unsubscribe(name, onceHandler); | |
handler.apply(self, args); | |
} | |
/* subscribe with the _new_ handler. */ | |
this.subscribe(name, onceHandler); | |
} | |
/** | |
* Invokes all subscriber functions subscribed to the event. | |
* @param {string} name of the event to emit | |
* @param {*} data provided to each subscriber. | |
*/ | |
emit(name, data) { | |
// handler is invoked with .call() to remove the EventEmitter context. | |
this.events[name] && this.events[name].forEach(handler => handler.call(null, data)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment