发布订阅

2021-06-27  本文已影响0人  lessonSam

最开始是听一位大佬讲 最开始的发布订阅库 是受dom 二级 事件的启发 后来经过封装 形成的一个库 那么 什么是发布订阅呢? 我自己的理解就是 我有计划的做某些事情 在未来某个时刻 执行这个计划清单

jQ 的 发布订阅 $.Callback 形成一个事件池 最后该事件 池 有 fire 事件进行触发! 不过遗憾的是 该事件池并没有 进行一个去重的处理
++下面是我的一个简单的发布订阅++
// 基于 es6 构建一个 自己的发布订阅库

//

let _subscribe = (function () {
    //=> Sub 发布订阅类
    class Subscribe {
        constructor() {
            //=> 创建一个事件池 用来存储 后期需要执行的方法
            this.$pond = []
        }
        //=> 往事件池当中 追加方法  做 重复处理
        add(func) {
            //  可以判断是否是函数类型 如果是 追加 不是就不追加
            // 如果 之前的方法存在改方法 就不做处理
            let flag = this.$pond.some(item=> {
                return item === func
            })
            //  之前发事件池 当中没有 追加 
            if(!flag) {
                this.$pond.push(func)
            }
        }
        remove(func) {
            //=> 
            let $pond = this.$pond;
            for(let i = 0; i< $pond.length; i++) {
                let item = $pond[i]
                if(item===func) {
                    //=> 不能修改顺序 基本上只能使用 splice 但是不能这样写 这样会导致 数组塌陷问题 我们移除不能真移除 只能把当前项 赋值 为 null
                    // $pond.splice(i,1)
                    $pond[i] = null
                    //=> 追加的时候做的有 去重处理 只要 删除一个就可以结束了
                    break;
                }
            }
        }
        //=> 通知事件池当中的方法 按照顺序 依次执行

        fire(...params) {
            //   发布
            // call 当执行的时候 保证每个函数的实例 仍然执行 当前实例
            for(let i = 0; i< this.$pond.length; i++ ){
                if (typeof this.$pond[i] !== 'function'){
                    //  此时再删除
                    this.$pond.splice(i,1)
                    i--
                    continue

                }
                this.$pond[i].call(this, ...params)
            }
        }
        
    }
    //  这样处理的好处是 可以每次使用的时候 可以直接当做函数使用 不必在外面使用new 关键字
    return function () {
        return new Subscribe()
    }
})()

上一篇下一篇

猜你喜欢

热点阅读