在实际开发中,经常会遇到某个方法内处理很多的逻辑,最简单的就是直接在方法内直接写。这种是高度耦合的面向过程的写法。对于代码维护不友好。而发布-订阅模式就是将两者分离。使用者触发了某个事件),使用者只向调度中心通知,并不关心调度中心内如何处理和响应次数。而订阅者只关心在调度中心订阅,有使用者调用它才响应。 下面定义了一个PubSub类,并实现了发布订阅模式:
class PubSub {
constructor() {
// 存储的订阅内容的数组,因为订阅者可能有多个
this.list = []
}
// 订阅
listen(key, fn) {
// 判断是否为空,如果是空就设置一个容器
if (!this.list[key]) {
this.list[key] = []
}
// 不是空就存进去
this.list[key].push(fn)
}
// 发布
trigger() {
// 取出传入的key
let key = Array.prototype.shift.call(arguments)
// 取出存储在里面的函数
let fns = this.list[key]
// 判断函数
if (!fns || fns.length == 0) {
return false
}
// 函数没问题的话就都执行
for (let i = 0, fn; fn = fns[i++];) {
fn(...arguments)
}
}
// 取消
remove(key, fn) {
let fns = this.list[key]
if (!fns) {
return false
}
// 如果没有fn, fns应该也是空的
if (!fn) {
fn && (fns.length = 0)
} else {
// 循环遍历要删除的fn(从最后一个开始)
for (let i = fns.length - 1; i > -1; i--) {
let _fn = fns[i]
if (_fn == fn) {
fns.splice(i, 1)
}
}
}
}
}