File size: 1,303 Bytes
87337b1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import { EventHandler } from "./types"
export class AGEventEmitter<T> {
private readonly _eventMap: Map<keyof T, EventHandler<any[]>[]> = new Map()
once<Key extends keyof T>(evt: Key, cb: T[Key]) {
const wrapper = (...args: any[]) => {
this.off(evt, wrapper as any)
;(cb as any)(...args)
}
this.on(evt, wrapper as any)
return this
}
on<Key extends keyof T>(evt: Key, cb: T[Key]) {
const cbs = this._eventMap.get(evt) ?? []
cbs.push(cb as any)
this._eventMap.set(evt, cbs)
return this
}
off<Key extends keyof T>(evt: Key, cb: T[Key]) {
const cbs = this._eventMap.get(evt)
if (cbs) {
this._eventMap.set(
evt,
cbs.filter((it) => it !== cb),
)
}
return this
}
removeAllEventListeners(): void {
this._eventMap.clear()
}
emit<Key extends keyof T>(evt: Key, ...args: any[]) {
const cbs = this._eventMap.get(evt) ?? []
for (const cb of cbs) {
try {
cb && cb(...args)
} catch (e) {
// cb exception should not affect other callbacks
const error = e as Error
const details = error.stack || error.message
console.error(
`[event] handling event ${evt.toString()} fail: ${details}`,
)
}
}
return this
}
}
|