134 lines
3.4 KiB
TypeScript
134 lines
3.4 KiB
TypeScript
export interface EventData<T = any> {
|
||
type: string;
|
||
data: T;
|
||
}
|
||
|
||
export type EventHandler<T = any> = (event: EventData<T>) => void;
|
||
|
||
export class EventEmitter {
|
||
private events: Map<string, Set<EventHandler>> = new Map();
|
||
|
||
/**
|
||
* 监听事件
|
||
* @param type 事件类型
|
||
* @param handler 事件处理函数
|
||
*/
|
||
on<T = any>(type: string, handler: EventHandler<T>): void {
|
||
if (!this.events.has(type)) {
|
||
this.events.set(type, new Set());
|
||
}
|
||
this.events.get(type)!.add(handler);
|
||
}
|
||
|
||
/**
|
||
* 移除事件监听器
|
||
* @param type 事件类型
|
||
* @param handler 事件处理函数 (可选,如果不提供则移除该类型的所有监听器)
|
||
*/
|
||
off<T = any>(type: string, handler?: EventHandler<T>): void {
|
||
if (!this.events.has(type)) {
|
||
return;
|
||
}
|
||
|
||
if (handler) {
|
||
this.events.get(type)!.delete(handler);
|
||
// 如果该类型没有监听器了,删除该类型
|
||
if (this.events.get(type)!.size === 0) {
|
||
this.events.delete(type);
|
||
}
|
||
} else {
|
||
// 移除该类型的所有监听器
|
||
this.events.delete(type);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 触发事件
|
||
* @param event 事件对象,包含 type 和 data
|
||
*/
|
||
emit<T = any>(event: EventData<T>): void {
|
||
const { type } = event;
|
||
|
||
if (!this.events.has(type)) {
|
||
return;
|
||
}
|
||
|
||
const handlers = this.events.get(type)!;
|
||
handlers.forEach(handler => {
|
||
try {
|
||
handler(event);
|
||
} catch (error) {
|
||
console.error(`Error in event handler for type "${type}":`, error);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 触发事件(简化版本,直接传递type和data)
|
||
* @param type 事件类型
|
||
* @param data 事件数据
|
||
*/
|
||
emitSimple<T = any>(type: string, data: T): void {
|
||
this.emit({ type, data });
|
||
}
|
||
|
||
/**
|
||
* 清空所有事件监听器
|
||
*/
|
||
clear(): void {
|
||
this.events.clear();
|
||
}
|
||
|
||
/**
|
||
* 获取指定类型的监听器数量
|
||
* @param type 事件类型
|
||
* @returns 监听器数量
|
||
*/
|
||
listenerCount(type: string): number {
|
||
return this.events.get(type)?.size || 0;
|
||
}
|
||
|
||
/**
|
||
* 获取所有事件类型
|
||
* @returns 事件类型数组
|
||
*/
|
||
eventNames(): string[] {
|
||
return Array.from(this.events.keys());
|
||
}
|
||
|
||
/**
|
||
* 检查是否有指定类型的监听器
|
||
* @param type 事件类型
|
||
* @returns 是否有监听器
|
||
*/
|
||
hasListeners(type: string): boolean {
|
||
return this.events.has(type) && this.events.get(type)!.size > 0;
|
||
}
|
||
|
||
/**
|
||
* 只监听一次事件
|
||
* @param type 事件类型
|
||
* @param handler 事件处理函数
|
||
*/
|
||
once<T = any>(type: string, handler: EventHandler<T>): void {
|
||
const onceHandler: EventHandler<T> = (event) => {
|
||
handler(event);
|
||
this.off(type, onceHandler);
|
||
};
|
||
this.on(type, onceHandler);
|
||
}
|
||
}
|
||
|
||
// 创建默认的事件发射器实例
|
||
export const eventEmitter = new EventEmitter();
|
||
|
||
// 导出便捷方法
|
||
export const on = <T = any>(type: string, handler: EventHandler<T>) => eventEmitter.on(type, handler);
|
||
export const off = <T = any>(type: string, handler?: EventHandler<T>) => eventEmitter.off(type, handler);
|
||
export const emit = <T = any>(event: EventData<T>) => eventEmitter.emit(event);
|
||
export const emitSimple = <T = any>(type: string, data: T) => eventEmitter.emitSimple(type, data);
|
||
export const clear = () => eventEmitter.clear();
|
||
export const once = <T = any>(type: string, handler: EventHandler<T>) => eventEmitter.once(type, handler);
|
||
|
||
// 默认导出
|
||
export default eventEmitter; |