Created
July 10, 2018 18:40
-
-
Save brunocalou/858349e1ad893a08bb2af667d576dc79 to your computer and use it in GitHub Desktop.
A simple yet powerful event system capable of dispatching events with any number of arguments
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
/** | |
* A simple yet powerful event system capable of dispatching events with any number of arguments | |
* | |
* @example | |
* const eventSystem = new EventSystem(); | |
* eventSystem.on('my-event', () => console.log('hello event system')); | |
* eventSystem.on('my-event', () => console.log('hello from here too')); | |
* | |
* // In the future | |
* eventSystem.dispatch('my-event'); | |
* | |
* // Output | |
* // hello event system | |
* // hello from here too | |
* | |
* @example | |
* const eventSystem = new EventSystem(); | |
* eventSystem.on('my-event-with-arguments', (arg1, arg2, arg3, arg4) => { | |
* console.log('hello event system'); | |
* console.log(arg1); | |
* console.log(arg2); | |
* console.log(arg3); | |
* console.log(arg4); | |
* }); | |
* | |
* // In the future | |
* eventSystem.dispatch('my-event-with-arguments', 'first argument', 2, { argument: 3 }, [4]); | |
* | |
* // Output | |
* // first argument | |
* // 2 | |
* // Object { argument: 3 } | |
* // Array [ 4 ] | |
* | |
* @example | |
* class Coffee { | |
* constructor({ | |
* flavor, | |
* quantity, | |
* }) { | |
* this.flavor = flavor; | |
* this.quantity = quantity; | |
* } | |
* | |
* drink() { | |
* this.quantity = 0; | |
* console.log('Yummy!'); | |
* } | |
* } | |
* | |
* class CoffeeMachine extends EventSystem { | |
* makeCoffee() { | |
* setTimeout(() => this.dispatch('coffee-ready', new Coffee('vanilla', 100), 1000)); | |
* } | |
* } | |
* | |
* const machine = new CoffeeMachine(); | |
* machine.on('coffee-ready', coffee => coffee.drink()); | |
* machine.makeCoffee(); | |
* | |
* // Output | |
* // Yummy! | |
*/ | |
export default class EventSystem { | |
constructor() { | |
this.events = {}; | |
} | |
/** | |
* Listens to an event | |
* @param {string} event The event to listen to | |
* @param {function} callback The function to call when the event is dispatched | |
* @param {object} context The context to use on the callback call | |
*/ | |
on(event, callback, context) { | |
if (this.events[event] === undefined) { | |
this.events[event] = []; | |
} | |
this.events[event].push({ | |
callback, | |
context, | |
}); | |
} | |
/** | |
* Removes a callback from an event. If the callback is undefined, all the callbacks for the | |
* specified event will be removed | |
* | |
* @example | |
* const eventSystem = new EventSystem(); | |
* const callback = () => console.log('callback was called'); | |
* | |
* eventSystem.on('my-event', callback); | |
* eventSystem.off('my-event', callback); | |
* eventSystem.dispatch('my-event'); | |
* // No Output | |
* | |
* @example | |
* const eventSystem = new EventSystem(); | |
* const callback = () => console.log('callback was called'); | |
* const anotherCallback = () => console.log('another callback was called'); | |
* | |
* eventSystem.on('my-event', callback); | |
* eventSystem.on('my-event', anotherCallback); | |
* eventSystem.off('my-event'); | |
* eventSystem.dispatch('my-event'); | |
* // No Output | |
* | |
* @param {string} event The event | |
* @param {function} callback The callback to be removed | |
*/ | |
off(event, callback) { | |
if (this.events[event] !== undefined) { | |
if (callback !== undefined) { | |
this.events[event] = this.events[event].filter(listener => listener.callback !== callback); | |
} else { | |
delete this.events[event]; | |
} | |
} | |
} | |
/** | |
* Dispatches an event | |
* @param {string} event The event to be dispatched | |
* @param {any} args The arguments to dispatch | |
*/ | |
dispatch(event, ...args) { | |
const listeners = this.events[event]; | |
if (listeners !== undefined) { | |
listeners.forEach(listener => listener.callback.call(listener.context, ...args)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Typescript version