import type { EventMap, CustomEventMap } from "../types/EventEmitter"; import type { PopsType } from "../types/main"; class EventEmiter { [Symbol.toStringTag] = "EventEmiter"; type: PopsType; data = new Map< string, { type: PopsType; time: number; callback: (...args: any[]) => IPromise; }[] >(); constructor(type: PopsType) { this.type = type; } on

( eventName: P, callback: EventMap[P] ): { off: () => IPromise; emit: (...args: Parameters) => IPromise; }; on

( eventName: P, callback: T[P] ): { off: () => IPromise; emit: (...args: Parameters) => IPromise; }; on

(eventName: P, callback: (EventMap & CustomEventMap)[P]) { const eventList = this.data.get(eventName) ?? []; eventList.push({ type: this.type, time: Date.now(), callback: callback }); this.data.set(eventName, eventList); return { off: () => { this.off(eventName as keyof EventMap, callback); }, emit: (...args: Parameters) => { this.emit(eventName, ...args); }, }; } off

(eventName: P, callback: EventMap[P]): IPromise; off

(eventName: P, callback: T[P]): IPromise; off

(eventName: P, callback: (EventMap & CustomEventMap)[P]) { const eventList = this.data.get(eventName) ?? []; let isOffSuccess = false; for (let index = eventList.length - 1; index >= 0; index--) { if (eventList[index].callback === callback) { isOffSuccess = true; eventList.splice(index, 1); } } if (eventList.length === 0) { // empty this.data.delete(eventName); } else { if (isOffSuccess) { // update this.data.set(eventName, eventList); } } } emit

(eventName: P, ...args: Parameters): IPromise; emit

(eventName: P, ...args: Parameters): IPromise; async emit

(eventName: P, ...args: Parameters) { const eventList = this.data.get(eventName) ?? []; for (const item of eventList) { await item.callback(...args); } } offAll

(eventName?: P): IPromise; offAll

(eventName?: P): IPromise; offAll

(eventName?: P) { if (typeof eventName === "string") { this.data.delete(eventName); } else { this.data.clear(); } } /** * 获取所有添加的事件 */ getAllEvents(eventName?: string) { if (typeof eventName === "string") { return this.data.get(eventName); } else { return Array.from(this.data.values()); } } } export { EventEmiter };