I wrote the following EventEmitter class, and it works great so far. But today I came across a scenario where if event listeners are created and destroyed frequently, and the off function is not used to remove the listener, there will be potential performance issues. How can I optimize this problem? Can anyone give me some ideas?
class EventEmitter {
private listeners: Record<string, [Set<Function>, Set<Function>]> = {};
existsEvent(eventName: string | number) {
return !!this.listeners[eventName];
}
on(eventName: string | number, listener: Function) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [new Set(), new Set()];
}
this.listeners[eventName][0].add(listener);
}
once(eventName: string | number, listener: Function) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [new Set(), new Set()];
}
this.listeners[eventName][1].add(listener);
}
emit(eventName: string | number, ...args: any[]) {
if (!this.listeners[eventName]) {
return
}
this.listeners[eventName][0].forEach((listener: Function) => {
listener(...args);
});
this.listeners[eventName][1].forEach((listener: Function) => {
listener(...args);
});
this.listeners[eventName][1].clear();
}
off(eventName: string | number, listener: Function) {
if (!this.listeners[eventName]) {
return;
}
if (typeof listener === 'function') {
this.listeners[eventName][0].delete(listener);
this.listeners[eventName][1].delete(listener);
} else {
this.listeners[eventName][0].clear();
this.listeners[eventName][1].clear();
}
}
}
export const eventEmitter = new EventEmitter();
To make good realization of Event Emitter like module need to have great knowledge of js architecture. That`s why most of cases developers use EE developed by big companies.
To learn how they implemented need to look for few examples like default Node JS Event Emitter:
https://github.com/nodejs/node/blob/main/lib/events.js
or used long time ago by Meta (Facebook) its own version of EE for other goals than included in node (now archived), but as example still good:
https://github.com/facebookarchive/emitter
This examples will help to understand main concepts which each EE must have.
But today I came across a scenario where if event listeners are created and destroyed frequently, and the off function is not used to remove the listener, there will be potential performance issues.
You need to use off
like methods or subscribe listeners via once
methods.