92 lines
2.1 KiB
TypeScript
92 lines
2.1 KiB
TypeScript
/** 事件处理器类型 */
|
|
type EventHandler = (...args: unknown[]) => void
|
|
|
|
/** 应用级事件常量 */
|
|
export const AppEvents = {
|
|
/** 401 未授权 */
|
|
UNAUTHORIZED: 'app:unauthorized',
|
|
/** 请求错误(业务错误 / HTTP 错误 / 网络错误) */
|
|
REQUEST_ERROR: 'app:request:error'
|
|
} as const
|
|
|
|
/**
|
|
* 发布订阅事件总线
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* // 注册事件
|
|
* eventBus.on(AppEvents.UNAUTHORIZED, () => {
|
|
* router.push('/auth/login')
|
|
* })
|
|
*
|
|
* // 发布事件
|
|
* eventBus.emit(AppEvents.UNAUTHORIZED)
|
|
* ```
|
|
*/
|
|
class EventBus {
|
|
/** 事件名 → 处理器集合 */
|
|
private handlers = new Map<string, Set<EventHandler>>()
|
|
|
|
/**
|
|
* 注册事件处理器
|
|
* @param event - 事件名
|
|
* @param handler - 处理器函数
|
|
*/
|
|
on(event: string, handler: EventHandler): void {
|
|
if (!this.handlers.has(event)) {
|
|
this.handlers.set(event, new Set())
|
|
}
|
|
this.handlers.get(event)!.add(handler)
|
|
}
|
|
|
|
/**
|
|
* 注册一次性事件处理器(触发后自动取消注册)
|
|
* @param event - 事件名
|
|
* @param handler - 处理器函数
|
|
*/
|
|
once(event: string, handler: EventHandler): void {
|
|
const wrapper: EventHandler = (...args: unknown[]) => {
|
|
handler(...args)
|
|
this.off(event, wrapper)
|
|
}
|
|
this.on(event, wrapper)
|
|
}
|
|
|
|
/**
|
|
* 取消注册事件处理器
|
|
* @param event - 事件名
|
|
* @param handler - 要取消的处理器函数
|
|
*/
|
|
off(event: string, handler: EventHandler): void {
|
|
this.handlers.get(event)?.delete(handler)
|
|
}
|
|
|
|
/**
|
|
* 发布事件
|
|
* @param event - 事件名
|
|
* @param args - 传递给处理器的参数
|
|
*/
|
|
emit(event: string, ...args: unknown[]): void {
|
|
const handlers = this.handlers.get(event)
|
|
if (!handlers) return
|
|
handlers.forEach((handler) => {
|
|
handler(...args)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 清除指定事件的所有处理器,或清除所有事件
|
|
* @param event - 可选,不传则清除全部
|
|
*/
|
|
clear(event?: string): void {
|
|
if (event) {
|
|
this.handlers.delete(event)
|
|
} else {
|
|
this.handlers.clear()
|
|
}
|
|
}
|
|
}
|
|
|
|
/** 事件总线单例 */
|
|
export const eventBus = new EventBus()
|