js发布订阅,为什么要将handler包装一层?
看到别人写的EventHub
,在监听事件的时候,他会给参数handler
套一层new EventListener()
,这样做的好处是什么?不将handler
抽象成listener
也同样可以实现,为什么要多此一举?
export class EventHub<E extends Emiter> { private cached: { [name in keyof E]: EventListener[] } = {} as any
/**
* @param: 监听的事件名
* @param: 事件的处理函数, 在事件触发时会被调用
*/
public on<N extends keyof E>(eventName: N, handler: Handler<E[N]>) {
if (!handler) { throw new Error('invaild handler') }
if (!this.cached[eventName]) { this.cached[eventName] = [] }
const listener = new EventListener(eventName as string, handler, this)
this.cached[eventName].push(listener)
}
/**
* @param eventName: 触发事件的名称
*/
public emit<N extends keyof E>(eventName: N, data: E[N] = null) {
const listeners = this.cached[eventName]
if (!eventName) { throw new Error('invaild eventName') }
listeners.forEach((listener) => {
listener.handler.call(this, data)
})
}
/**
* @param eventName: 注销事件的名称
* @param target: 需要注销的事件
* 不传入 target 默认注销整个事件
*/
public off<N extends keyof E>(eventName: N, target?: EventListener): boolean {
if (!this.cached[eventName]) { return false }
if (!target) {
this.cached[eventName] = [];
delete this.cached[eventName];
return true;
}
for (let listeners = this.cached[eventName], i = 0; i < listeners.length; i++) {
const listener = listeners[i]
if (listener !== target) { continue }
this.cached[eventName] = this.cached[eventName].filter((l) => {
return l !== listener
})
listener.distory()
}
if (this.cached[eventName].length === 0) {
delete this.cached[eventName]
return true
}
return false
}
}
回答:
基础的发布订阅模式是不需要对handler进行封装的,这里使用EventListener类对handler进行封装可能是对handler进行统一管理或者使用前的处理,这在复杂项目中很常见
以上是 js发布订阅,为什么要将handler包装一层? 的全部内容, 来源链接: utcz.com/p/935743.html