发布订阅模式:是模拟DOM2级事件的事件池思想,在某一个时刻到来时,我们要做很多的事情(很多函数)。我们准备一个数组当做一个事件池,并且提供向事件池中加入函数的方法以及移除的方法,当时刻来临时,我们把事件池中的方法取出来挨个执行;
发布订阅:
订阅:订阅该时刻到来,把想做的事情加入事件池 发布:时刻真的到来了,把事件池中的方法都执行了
// 准备事件池:
let ary = [];
function addListener(fn) {
if (ary.includes(fn)) return;
ary.push(fn)
}
function removeListener(fn) {
// 数组.filter 方法,把数组中满足条件的(回调函数返回true的项)组成一个新数组,原数组不变;
ary = ary.filter(item => item !== fn);
}
function fire() {
ary.forEach(item => item())
}
function fn1(_this) {
console.log(1)
}
function fn2() {
console.log(3)
}
function fn3() {
console.log(3)
}
// 订阅5s后的这个时刻
add(fn1);
add(fn2);
add(fn3);
// 取消订阅
removeListener(fn3);
setTimeout(function () {
// 5s后时刻来临,就把事件池中的方法都执行了
fire(this);
}, 5000);
封装发布订阅
class Subscribe {
constructor () {
this.pond = [];
}
includes (fn) {
// 判断当前事件池是否包含某一个函数
return this.pond.includes(fn);
}
addListener (fn) {
// 不能重复添加
if (!this.includes(fn)) this.pond.push(fn);
return this;
}
removeListener (fn) {
// 取消订阅
if (this.includes(fn)) {
this.pond = this.pond.filter(item => item !== fn);
}
return this;
}
fire (...args) {
// 等到时刻到来时把事件池中的的函数都执行了
this.pond.forEach(item => item(...args));
}
}
function fn1() {
console.log(1)
}
function fn2() {
console.log(2)
}
function fn3() {
console.log(3)
}
let plan = new Subscribe();
plan.addListener(fn1).addListener(fn2).addListener(fn3);
setTimeout(() => plan.fire([1, 2, 3]), 5000);