|
class EventsEmitter { |
|
constructor(){ |
|
this.events = {}; |
|
} |
|
on(name, callback, context, once = false){ |
|
if(name == null) throw new Error('No first argument passed'); |
|
if(callback == null) throw new Error('No second argument passed'); |
|
if(typeof callback !== 'function') throw new Error('Second argument must be a function'); |
|
|
|
if(typeof context === 'boolean' && context === true && once === false){ |
|
[once, context] = [context, null]; |
|
} |
|
|
|
this.events[name] = [...(this.events[name] || []), {callback, context, once}]; |
|
} |
|
off(name, callback){ |
|
if(name == null) throw new Error('No first argument passed'); |
|
if(!this.events[name]) return; |
|
|
|
if(callback){ |
|
if(callback == null) throw new Error('No second argument passed'); |
|
if(typeof callback !== 'function') throw new Error('Second argument must be a function'); |
|
this.events[name] = this.events[name].filter(event=>event.callback != callback); |
|
} |
|
else{ |
|
delete this.events[name]; |
|
} |
|
} |
|
emit(name, ...args){ |
|
if(name == null) throw new Error('No first argument passed'); |
|
|
|
(this.events[name] || []).forEach(event=>{ |
|
try{ |
|
event.callback.call(event.context, ...args); |
|
|
|
if(event.once){ |
|
this.off(name, event.callback); |
|
} |
|
} |
|
catch(e){ |
|
throw e; |
|
} |
|
}); |
|
} |
|
|
|
//aliases |
|
once(name, callback, context){ |
|
this.on(name, callback, context, true); |
|
} |
|
subscribe(name, callback, context){ |
|
this.on(name, callback, context); |
|
} |
|
unsubscribe(name, callback){ |
|
this.off(name, callback); |
|
} |
|
addListener(name, listener, context){ |
|
this.on(name, listener, context); |
|
} |
|
removeListener(name, listener){ |
|
this.off(name, listener); |
|
} |
|
removeListeners(name){ |
|
this.off(name); |
|
} |
|
dispatchEvent(name, ...args){ |
|
this.emit(name, ...args); |
|
} |
|
} |
|
export default EventEmitter; |