async/await异步事件总线核心是让监听器自然返回Promise并可控等待:支持并行(Promise.all)或串行(for...of+await)执行,内置错误隔离、取消信号与超时机制,结合泛型类型安全及off/once/destroy生命周期管理。

用 async/await 实现异步事件总线,核心是让监听器能自然返回 Promise,同时确保事件触发时能正确等待所有异步监听器完成(或按需并发/串行执行),而不是简单地“发完就不管”。
监听器支持 async,触发时 await 所有回调
事件总线的 on 方法照常注册函数,但 emit 不再只是循环调用,而是收集所有监听器的返回值(Promise),用 Promise.all 或 for...of + await 控制执行顺序。
- 若希望监听器并行执行(常见):用
Promise.all(listeners.map(fn => fn(...args))) - 若要求严格串行(如状态依赖):用
for (const fn of listeners) await fn(...args) - 注意捕获单个监听器错误,避免一个失败导致整个链路中断(可用
.catch(() => {})或封装成safeCall)
支持取消与超时(可选但实用)
真实场景中,某些监听器可能卡住或无需继续执行。可在 emit 时接受 AbortSignal 或 timeout 选项:
- 传入
{ signal },在每个监听器调用前检查signal.aborted - 用
Promises.race([fn(), timeoutPromise])包裹每个监听器,超时则 reject 或忽略 - 不强制所有监听器都支持取消,但提供统一入口让上层可控
类型安全与泛型设计(TypeScript 场景)
用泛型约束事件名和对应参数,避免 any 泛滥:
- 定义
type Events = { 'user:login': [User]; 'order:paid': [Order, string] } on<k extends keyof events>(event: K, fn: (...args: Events[K]) => Promise<void>): void</void></k>emit<k extends keyof events>(event: K, ...args: Events[K]): Promise<void></void></k>- 这样调用
bus.emit('user:login', user)时,TS 能校验参数数量和类型
避免内存泄漏:提供 off 和自动清理机制
异步监听器本身不会增加泄漏风险,但长期运行的总线需管理订阅生命周期:
-
off(event, fn)必须精确匹配(建议用 WeakMap 存储 listener → handler 映射) - 支持一次性监听:
once(event, fn)内部自动在首次调用后off - 对组件/模块级使用,可返回
destroy()方法批量清空该上下文的所有监听器

















