diff options
Diffstat (limited to 'src/Event/EventEmitter.js')
-rw-r--r-- | src/Event/EventEmitter.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/Event/EventEmitter.js b/src/Event/EventEmitter.js new file mode 100644 index 0000000..3a6db25 --- /dev/null +++ b/src/Event/EventEmitter.js @@ -0,0 +1,127 @@ +export default class EventEmitter { + + constructor() { + this._listeners = {}; + this._once = {}; + } + + /** + * @param {String|String[]} event + * @param {Object} data + * + * @return {Promise<void>} + */ + async emit(event, data) { + if(Array.isArray(event)) { + event.forEach((event) => {this.emit(event, data);}); + return; + } + + await this._notifyListeners(event, data); + await this._notifyOnce(event, data); + } + + /** + * @param {String|String[]} event + * @param {Function} callback + * + * @return EventEmitter + */ + on(event, callback) { + if(Array.isArray(event)) { + event.forEach((event) => {this.on(event, callback);}); + return this; + } + + if(!this._listeners.hasOwnProperty(event)) { + this._listeners[event] = []; + } + + this._listeners[event].push(callback); + + return this; + } + + /** + * @param {String|String[]} event + * @param {Function} callback + * + * @return EventEmitter + */ + off(event, callback) { + if(Array.isArray(event)) { + event.forEach((event) => {this.off(event, callback);}); + return this; + } + + if(!this._listeners.hasOwnProperty(event)) { + return this; + } + + for(let i = 0; i < this._listeners[event].length; i++) { + if(this._listeners[event][i] === callback) { + this._listeners[event].splice(i, 1); + i--; + } + } + + return this; + } + + /** + * @param {String} event + * @param {Function} callback + * + * @return EventEmitter + */ + once(event, callback) { + if(!this._once.hasOwnProperty(event)) { + this._once[event] = []; + } + + this._once[event].push(callback); + + return this; + } + + /** + * @param {String} event + * @param {Object} data + * @return {Promise<void>} + * @private + */ + async _notifyListeners(event, data) { + if(!this._listeners.hasOwnProperty(event)) { + return; + } + + for(let callback of this._listeners[event]) { + try { + await callback(data); + } catch(e) { + console.error(e); + } + } + } + + /** + * @param {String} event + * @param {Object} data + * @return {Promise<void>} + * @private + */ + async _notifyOnce(event, data) { + if(!this._once.hasOwnProperty(event)) { + return; + } + + let callback; + while(callback = this._once[event].pop()) { + try { + await callback(data); + } catch(e) { + console.error(e); + } + } + } +}
\ No newline at end of file |