Skip to content

Instantly share code, notes, and snippets.

@ferco0
Last active May 13, 2018 07:15
Show Gist options
  • Save ferco0/e8427b95e2567cbe1b702986e3c24c92 to your computer and use it in GitHub Desktop.
Save ferco0/e8427b95e2567cbe1b702986e3c24c92 to your computer and use it in GitHub Desktop.
Events emitter and handler with pre-cached emitts in typescript
/**
*
* EventEmitter
* @description Events emitter and handler with pre-cached and timed emitters
* @author Fernando Costa <ferco0@live.com>
*
*/
interface IEventEmitter{
listeners: any
emitts: any
emit(eventName: string, data: any): void
timed(eventName: string, data, time: number): void
registryListener(eventName: string, callback: ( data?: any) => void ): void
on(eventName: string, callback: ( data?: any) => void , once: boolean): void
once(eventName: string, callback: ( data?: any) => void ): void
remove(eventName: string, callback: ( data?: any) => void ): void
}
/**
* Class EventEmitter
* @class
*/
class EventEmitter implements IEventEmitter{
/**
* @description The events listeners
* @type {Object}
*/
listeners: any = {}
/**
* @description Cached emitts
* @type {array}
*/
emitts: any[] = []
/**
* @description Emit and cache for future listeners
* @param {stirng} eventName - The event indentifier
* @param {mixin} data - Opitional data
* @return {void}
*/
emit(eventName: string, data: any = false): void {
if(typeof this.emitts[eventName] === 'undefined')
this.emitts[eventName] = []
this.emitts[eventName].push(data);
if(typeof this.listeners[eventName] !== 'undefined'){
let listenersLength = this.listeners[eventName].length;
let count = 0;
for(; count < listenersLength; ++count){
this.listeners[eventName][count].call(this, data );
}
}
}
/**
* @description Timed emitter
* @param {string} eventName - The event indentifier
* @param {mixin} data - Opitional data
* @param {number} time - The time of delay
* @return {void}
*/
timed(eventName: string, data = false, time: number): void {
setTimeout( () => {
this.emit(eventName, data);
}, time)
}
/**
* @description Register listener
* @param {string} eventName - The event indentifier
* @param {callback} callback - The callback handler
* @return {void}
*/
registryListener(eventName: string, callback: ( data?: any) => void ): void {
if(typeof this.listeners[eventName] === 'undefined')
this.listeners[eventName] = [];
this.listeners[eventName].push( callback );
}
/**
* @description Register listener
* @param {string} eventName - The event indentifier
* @param {callback} callback - The callback handler
* @param {boolean} once - Check if is one-time execution
* @return {void}
*/
on(eventName: string, callback: ( data?: any) => void , once: boolean = false): void {
if(this.emitts.hasOwnProperty(eventName)){
let length = this.emitts[eventName].length;
let count = 0;
for(; count < length; ++count){
callback.call(this, this.emitts[eventName][count]);
if(once) break;
}
if(!once) this.registryListener(eventName, callback);
}
else{
this.registryListener(eventName, callback);
}
}
/**
* @description One-time execution listener
* @param {string} eventName - The event indentifier
* @param {callback} callback - The callback handler
* @return {void}
*/
once(eventName: string, callback: ( data?: any) => void ): void {
this.on(eventName, function _once(data){
callback.call(this, data);
this.remove(eventName, _once);
}, true)
}
/**
* @description Remove listener
* @param {string} eventName - The event indentifier
* @param {callback} callback - The callback handler
* @return {void}
*/
remove(eventName: string, callback: ( data?: any) => void ): void {
if(this.listeners.hasOwnProperty(eventName)){
let index = this.listeners[eventName].indexOf( callback );
if (index > -1) {
this.listeners[eventName].splice(index, 1);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment