//基于es6自己封装发布订阅库 jQ中的发布订阅没有去重的功能
let _subscribe = function(){
//SUB :发布订阅类
class Sub{
constructor(){
//创建一个事件池,用来存储后期需要执行的方法
this.$pond = [];
}
//给事件池追加方法(做重复处理)
add(func){
let flag = this.$pond.some(item=>{
return item === func;
});
!flag ? this.$pond.push(func) : null;
}
//从事件池中移除方法
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(...args){
let $pond =this.$pond;
for(let i = 0; i< $pond.length;i++){
let item = $pond[i];
if(typeof item !== 'function'){
//此时再删除
$pond.splice(i,1);
i--;
continue;
}
item.call(this, ...args)
}
}
}
//暴露给外面用
return function subscribe(){
return new Sub();
}
}();
//使用 let s1 = _subscribe();
//事件池中移出事件导致的数组塌陷问题:fire的时候通知事件执行时,拿循环的索引i去对应数组的下标,当有事件被移除时,数组发生变化,但是去对应的索引i继续去对应,会导致事件中某几项被跳过.
//解决:移除用假装移除,把当前项改成null,这样索引还是不变.真正移除在fire的时候去进行,此时fire时需检查执行的是否为function