Skip to content

Instantly share code, notes, and snippets.

@jarek-foksa
Created December 15, 2014 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarek-foksa/a6a1b03e78b94735d35b to your computer and use it in GitHub Desktop.
Save jarek-foksa/a6a1b03e78b94735d35b to your computer and use it in GitHub Desktop.
export default class EventEmitter {
// @type
// (string, Function) => void
addEventListener(eventName, listener) {
if (!this._events) {
this._events = {};
}
let listeners = this._events[eventName];
if (!listeners) {
this._events[eventName] = listeners = [];
}
listeners.push(listener);
if (listeners.length > 20) {
console.warn(`Potential EventEmitter memory leak: ${listeners.length} listeners ` +
`subscribed to event "${eventName}"`);
}
}
// @type
// (string, Function) => void
removeEventListener(eventName, listener) {
if (!this._events || !this._events[eventName]) {
return;
}
var temp = [];
for (var i = 0; i < this._events[eventName].length; i += 1) {
if (this._events[eventName][i] !== listener) {
temp.push(this._events[eventName][i]);
}
}
this._events[eventName] = temp;
}
// @type
// (string, Array<Any>) => void
dispatchEvent(eventName, ...args) {
if (!this._events) {
return;
}
let listeners = this._events[eventName];
if (!listeners) {
return;
}
// If there is an error in any of the listeners then it will be thrown only after all
// listeners were fired, this is necesarry to prevent error in one listener from stopping
// all subsequent listeners
let catchedError = null;
for (let i = listeners.length-1; i >= 0; i -= 1) {
let listener = listeners[i];
let result;
try {
result = listener.apply(window, args);
}
catch (error) {
if (catchedError === null) {
catchedError = error;
}
}
// Stop event propagation if listener returns false
if (result === false) {
break;
}
}
if (catchedError) {
throw catchedError;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment