发布订阅模式
发布订阅模式关键是要有一个事件池,并通过这个事件池可以增加和删除方法,以此来对执行的函数进行一个统一管控,js的事件池类似于一个发布订阅模式。
let _subscribe = function(){
class Sub {
constructor() {
//添加事件池来存储后期执行的方法
this.pond = [];
}
// 向事件池添加方法,并先做判断(是否为函数并且pond中还未添加同一方法)
add(func) {
if (typeof func === 'function' && !this.pond.some(item => item === func)) {
this.pond.push(func)
}
}
//删除事件池的方法
remove(func) {
let ind = this.pond.indexOf(func);
if (ind !== -1) {
//直接用splice移出时,可能会导致数组塌陷,所以在这里赋值为null
// this.pond.splice(ind, 1);
this.pond[ind] = null;
}
}
//通知事件池中的方法按照顺序依次执行
notice(...args){
//这里使用 i--来解决数组塌陷,所以不可以在for循环条件内let len = this.pond.length
for(let i = 0;i < this.pond.length;i ++){
if(typeof this.pond[i] !== 'function'){
this.pond.splice(i,1);
i--;
continue;
}else{
this.pond[i](...args);
}
}
这里使用forEach方法,但是 因为没有很好的解决数组塌陷问题,所以还是使用for循环,希望 有大佬可以帮忙指导。
// this.pond.forEach((item,ind,array)=> {
// if(typeof item !== 'function'){
// this.pond.splice(ind,1);
// ind--;
// }else{
// this.pond[ind](...args);
// }
// })
}
}
// 暴漏给外界,不需要每次都执行new
return function subscribe(){
return new Sub();
}
}();