- 如果图不理解,先看下面的实现,读懂以后看图,就很清楚明了
type Event = keyof EventsType
type EventPrams<T extends Event> = EventsType[T]
type EventAction<T extends Event> = (data?: EventPrams<T>) => void
class SubScribeEvent {
static instance: SubScribeEvent | null
allEvents = new Map<Event, EventAction<Event>[]>()
on (eventName: Event, eventAction: EventAction<typeof eventName >) {
const hasEvent = this.allEvents.has(eventName)
if(!hasEvent) {
this.allEvents.set(eventName, [eventAction])
}else {
const curFns = this.allEvents.get(eventName)
this.allEvents.set(eventName, [...curFns, eventAction])
}
}
off(eventName: Event, eventAction?: EventAction<typeof eventName >) {
if(!eventAction) {
this.allEvents.delete(eventName)
}else {
const fns = this.allEvents.get(eventName)
const index = fns.indexOf(eventAction)
index !== -1 && fns.splice(index, 1)
this.allEvents.set(eventName, fns)
}
}
emit(eventName: Event, params?: EventPrams<typeof eventName>) {
if(!this.allEvents.has(eventName)) {
throw new Error(`${eventName} is not defined`)
}
const fns = this.allEvents.get(eventName)
fns.forEach(fn => fn(params))
}
has(eventName: Event) {
if(!eventName) return false
return this.allEvents.has(eventName)
}
static getSubScribeEvent() {
if(!this.instance) {
this.instance = new SubScribeEvent()
}
return this.instance
}
}
export default SubScribeEvent.getSubScribeEvent()
- instance 静态属性 ,保存当前SubScribeEvent 的实例,单例模式
- on 方法 ,绑定/订阅事件,判断事件是否被绑定过,没有则set,有则push
event.on('closeModal', (p) => {
console.log( 'closeModal事件'+p)
})
- off 解绑事件,事件触发完以后,都要执行解绑事件操作,否则会造成内存泄露。
- 注意:一个事件名可能对应多个绑定的事件,所以要指定解除某个事件时,必须要相同的函数引用。
const event1 = (p) => {
console.log('我是事件1'+p)
}
const event2 = (p) => {
console.log('我是事件2'+p)
}
event.on('closeModal', event1)
event.on('closeModal', event2)
event.off('closeModal', event1)
event.off('closeModal', () => {})
- emit 触发事件 / 发布事件,循环触发所有订阅的事件。
event.emit('closeModal', '触发了')
- has 查询某个事件是否订阅
event.has('closeModal')
event.has('otherFn')
- getSubScribeEvent 是一个静态方法,返回唯一一个实例,单例模式的具体应用。
- 使用时SubScribeEvent 只能存在一个,如果存在多个,会存在一系列的问题。