feat: 自定义emitter

This commit is contained in:
unanmed 2023-11-14 22:20:30 +08:00
parent 8a8dee3176
commit 9271e25dd9

View File

@ -15,12 +15,21 @@ interface ListenerOptions {
immediate: boolean; immediate: boolean;
} }
type EmitFn<F extends (...params: any) => any> = (
events: Listener<F>[],
...params: Parameters<F>
) => any;
export class EventEmitter<T extends EmitableEvent = {}> { export class EventEmitter<T extends EmitableEvent = {}> {
private events: { private events: {
[P in keyof T]?: Listener<T[P]>[]; [P in keyof T]?: Listener<T[P]>[];
} = {}; } = {};
private emitted: (keyof T)[] = []; private emitted: (keyof T)[] = [];
private emitter: {
[P in keyof T]?: EmitFn<T[P]>;
} = {};
/** /**
* *
* @param event * @param event
@ -74,19 +83,38 @@ export class EventEmitter<T extends EmitableEvent = {}> {
* @param event * @param event
* @param params * @param params
*/ */
emit<K extends keyof T>(event: K, ...params: Parameters<T[K]>) { emit<K extends keyof T>(
event: K,
...params: Parameters<T[K]>
): ReturnType<T[K]>[];
emit<K extends keyof T, R>(event: K, ...params: Parameters<T[K]>): R;
emit<K extends keyof T>(event: K, ...params: Parameters<T[K]>): any {
if (!this.emitted.includes(event)) { if (!this.emitted.includes(event)) {
this.emitted.push(event); this.emitted.push(event);
} }
const events = (this.events[event] ??= []); const events = (this.events[event] ??= []);
if (!!this.emitter[event]) {
const returns = this.emitter[event]!(events, ...params);
this.events[event] = events.filter(v => !v.once);
return returns;
} else {
const returns: ReturnType<T[K]>[] = [];
for (let i = 0; i < events.length; i++) { for (let i = 0; i < events.length; i++) {
const e = events[i]; const e = events[i];
e.fn(...(params as any)); returns.push(e.fn(...(params as any)));
if (e.once) { }
events.splice(i, 1); this.events[event] = events.filter(v => !v.once);
i--; return returns;
} }
} }
/**
* (emitter)
* @param event
* @param fn
*/
setEmitter<K extends keyof T>(event: K, fn?: EmitFn<T[K]>) {
this.emitter[event] = fn;
} }
/** /**