实现JS的发布订阅模式

176 阅读1分钟

在实际开发中,经常会遇到某个方法内处理很多的逻辑,最简单的就是直接在方法内直接写。这种是高度耦合的面向过程的写法。对于代码维护不友好。而发布-订阅模式就是将两者分离。使用者触发了某个事件),使用者只向调度中心通知,并不关心调度中心内如何处理和响应次数。而订阅者只关心在调度中心订阅,有使用者调用它才响应。 下面定义了一个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)
                }
            }
        }
    }
}