前言
作为一个大龄前端,终于开始学习TS了。。。恰巧也在看各种设计模式的内容,那就尝试来写一个,同事希望大家轻喷,欢迎指正。下面我开始表演(献丑)。。。
关于发布 “发布订阅模式” 与 “观察者模式” 的个人见解
个人理解发布订阅模式即,多个订阅事件与多个订阅回调函数的“多对多”关系;而观察者模式即,多个订阅回调都只能订阅指定的一个事件,即一对多关系。类比ts与js的关系,发布订阅模式是观察者模式的超集,几乎可以实现他的一切功能。
TS实现的具体代码如下
interface cache {
[propName: string]: Array<Function>;
}
export class EventBus {
cacheObject: cache = {}
constructor() {
console.log("EventBus注册成功!")
}
// 添加订阅
on(key: string, cb: (...args: any[]) => void): void {
if (typeof key !== 'string') throw new Error(`Error:订阅属性需要为字符串类型!`)
if (cb === undefined) throw new Error(`Error:请传入订阅属性的回调函数!`)
if (!this.cacheObject[key]) this.cacheObject[key] = []
if (cb.name === '' || !this.cacheObject[key].includes(cb)) this.cacheObject[key].push(cb)
}
// 取消订阅
off(key: string, cb: (...args: any[]) => void): void | Error {
if (!this.cacheObject[key]) {
throw new Error(`Error:还没有订阅${key}属性!`)
}
if (cb === undefined) throw new Error(`Error:请传入取消订阅属性的回调函数!`)
for (let [index, item] of this.cacheObject[key].entries()) {
if (item === cb) {
this.cacheObject[key].splice(index, 1)
break
}
}
}
// 取消指定属性下的全部订阅
offAll(key: string): void | Error {
if (!this.cacheObject[key]) {
throw new Error(`Error:还没有订阅${key}属性!`)
}
Reflect.deleteProperty(this.cacheObject, key)
}
// 触发订阅
emit(key: string, ...restParams: string[]): void | Error {
if (!this.cacheObject[key]) {
throw new Error(`Error:还没有订阅${key}属性!`)
}
for (let fn of this.cacheObject[key]) {
if (typeof fn === 'function') {
(<Function>fn).apply(this, restParams)
}
}
}
}
好了今天就说这么多,第一次在掘金上发帖,希望大家多多指正,共同进步。撒花。。。