发布订阅
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()
}
})()