type ObjectKey = string | number | symbol
type AnyFunction = (...args: any[]) => any
class EventBus {
// Map<eventName, Map<originalCallback, callback>>
// originalCallback 用于取消 once 注册的回调
private events: Map<ObjectKey, Map<AnyFunction, AnyFunction>>
constructor() {
this.events = new Map()
}
// 使用泛型的原因:...args 有类型,方便代码提示和类型检查
emit<T extends AnyFunction>(eventName: ObjectKey, ...args: Parameters<T>) {
const events = this.events.get(eventName)
if (!events) {
return
}
events.forEach(callback => {
callback(...args)
})
}
on<T extends AnyFunction>(eventName: ObjectKey, callback: T) {
this._on(eventName, callback, callback)
}
once<T extends AnyFunction>(eventName: ObjectKey, callback: T) {
// 包装方法:执行一次后取消订阅
const wrapper = (...args: Parameters<T>) => {
callback(...args)
this.off(eventName, callback)
}
this._on(eventName, wrapper, callback)
}
off<T extends AnyFunction>(eventName: ObjectKey, callback: T): boolean {
const events = this.events.get(eventName)
if (!events) {
return false
}
return events.delete(callback)
}
offAll(eventName: ObjectKey): boolean {
return this.events.delete(eventName)
}
private _on(eventName: ObjectKey, callback: AnyFunction, originalCallback: AnyFunction) {
let events = this.events.get(eventName)
if (!events) {
events = new Map()
this.events.set(eventName, events)
}
events.set(originalCallback, callback)
}
}