class EventMitter {
private _events: Record<string, Function[]>;
constructor() {
this._events = Object.create(null);
}
on(eventName: string, fn: Function) {
if (typeof fn !== "function") {
throw new TypeError("The event-triggered callback must be a function");
}
this._events[eventName]
? this._events[eventName].push(fn)
: (this._events[eventName] = [fn]);
}
emit(eventName: string, ...args: any[]) {
if (!this._events[eventName]) return false;
const fns = [...this._events[eventName]]
fns.forEach(fn => {
fn.apply(this, args)
})
return true;
}
once(eventName: string, fn: Function) {
const execFn = () => {
fn.apply(this)
this.off(eventName, execFn)
}
this.on(eventName, execFn)
}
off(eventName: string, fn?: Function) {
if (!this._events[eventName]) return;
if (!fn) {
this._events[eventName] && (this._events[eventName].length = 0)
}
let cb;
let cbLen = this._events[eventName].length
for (let i = 0; i < cbLen; i++) {
cb = this._events[eventName][i];
if (cb === fn) {
this._events[eventName].splice(i, 1)
break;
}
}
}
removeAllListeners(eventName?: string) {
if (eventName) {
this._events[eventName] && (this._events[eventName].length = 0)
} else {
this._events = Object.create(null)
}
}
}