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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| class EventBus { constructor() { this.listeners = new Map() this.wildcards = new Set() this.batchHandlers = new WeakMap() }
on(events, handler) { if (typeof events === 'string') events = [events] events.forEach(event => this._registerEvent(event, handler)) }
ons(events, handler) { const wrapper = (...args) => handler(...args) this.batchHandlers.set(handler, wrapper) events.forEach(event => this._registerEvent(event, wrapper)) }
emit(event, ...args) { if (this.listeners.has(event)) { this.listeners.get(event).forEach(handler => handler(...args)) }
this.wildcards.forEach(({ pattern, handler }) => { if (pattern.test(event)) handler(...args) }) }
off(event, handler) { const handlers = this.listeners.get(event) if (handlers) handlers.delete(handler) }
offs(events, handler) { const wrapper = this.batchHandlers.get(handler) if (!wrapper) return
events.forEach(event => { const handlers = this.listeners.get(event) if (handlers) handlers.delete(wrapper) }) this.batchHandlers.delete(handler) }
_registerEvent(event, handler) { if (event.includes('*')) { this.wildcards.add({ pattern: event.includes('.') ? new RegExp(`^${event.replace(/\.\*/g, '\\..*')}$`) : new RegExp(`^${event.replace(/\*/g, '.*')}$`), handler }) } else { if (!this.listeners.has(event)) this.listeners.set(event, new Set()) this.listeners.get(event).add(handler) } } }
|
Gitalk 加载中 ...