发布-订阅模式
发布-订阅模式和观察者模式的工作方式很相近,一个区别是,观察者模式种,观察者直接从它所观察的试题那里得到通知,而在发布-订阅模式,订阅者通过渠道得到通知,渠道位于发布者和订阅者之间来回传递信息。
jquery的发布-订阅方法
//开辟一个容器
let container = $.callBack();
//往容器里面订阅函数事件
container.add(function(){
console.log("订阅事件")
})
//发布事件
container.fire(function(){
console.log("发布事件")
})
//移除事件
container.remove(function(){
console.log("移除事件")
})
手动实现发布-订阅模式
class Subscribe{
constructor(){
//创建一个事件池,用来存储需要执行的方法
this.pond = [];
}
add(fn){
let flag = this.pond.some(item =>{
return item === fn;
})
!flag ? this.pond.push(fun) : null;
}
remove(fn){
let pnd = this.pond;
pond.forEach((item,index) =>{
if(item === fn){
//设置item = null 是无效的
pond[index] = null;
}
})
}
fire(...arg){
let pond = this.pond;
for(let i=0;i<pond.length;i++){
//如果item为null,则把它删除
if(item === null){
//防止使用循环中使用splice,数组塌陷问题,即删除一个元素后,后面所有元素的索引默认都会减1
pond.splice(i,1);
i--;
continue;
}
item(...arg);
}
}
}
let subscribe = new Subscribe();
let fn1 = function fn1(){
console.log("注册事件1")
}
let fn2 = function fn2(){
console.log("注册事件2")
}
subscribe.add(fn1)
subscribe.add(fn2)
subscribe.fire()
//订阅两个事件,事件1和事件2,发布会按顺序执行两个事件
//打印结果
//注册事件1
//注册事件2
//移除事件事件1
subscribe.remove(fn1)
subscribe.fire()
//打印结果
//注册事件2
踩坑记录
数组塌陷问题
什么是数组塌陷
在对数组进行遍历循环等操作时,会使数组的长度产生变化,同时操作的数组那个项的下一个索引会被跳过,从而造成数组的某项会被跳过,这种叫做数组塌陷现象。
注意:删除后数组的索引还是保持连续的。
解决方法
- 索引自减1
let arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {
arr.splice(i, 1);
i--;
}
- 由后往前循环(不推荐)
let arr = [1, 2, 3, 4];
for (let i = arr.length - 1; i >= 0; i--) {
arr.splice(i, 1);
}
但是又引入新问题,遍历后时执行顺序时颠倒的,不太符合我们的预期,之后针对这情况需要进一步处理。如执行前先反转数组。