发布订阅:灵感来源于 DOM2 事件池机制
- 事件池:可以向事件池中追加方法(追加多个不同的方法),当后期事件触发的时候,按照顺序会把这些方法依次执行(也可以从事件池中移除方法);
- 追加方法类似 addEventListener;
- 移除方法类似 removeEventListener;
图解
- 可以把要执行的方法,依次加入到池子中 on(也可以从池子中移除 off),当某个条件到达的时候,通知池子中的方法依次执行 emit;
jQuery 实现
// 创建一个事件池
let $plan = $.Callbacks();
function fn1(n, m) { console.log(1, n, m); }
function fn2(n, m) { console.log(2, n, m); }
function fn3(n, m) { console.log(3, n, m); }
// 向事件池中追加方法(没有做去重处理)
$plan.add(fn1);
$plan.add(fn2);
$plan.add(fn3);
$plan.add(fn3);
// 通知事件池中的方法执行
setTimeout(() => {
$plan.fire(10, 20);
}, 1000);
js 实现
(function () {
class EventBus {
constructor() {
// 创建一个事件池 {xxx:[],...}
this.pond = {};
}
// 向事件池中追加方法
$on(type, func) {
// 每一次加方法的时候,首先看看事件池中是否存在这个类型,不存在就创建
let pond = this.pond;
!(type in pond) ? pond[type] = [] : null;
// 增加方法(去重)
let pondT = pond[type];
!pondT.includes(func) ? pondT.push(func) : null;
}
// 从事件池中移除方法
$off(type, func) {
let pondT = this.pond[type];
if (!pondT) return;
for (let i = 0; i < pondT.length; i++) {
let item = pondT[i];
if (item === func) {
// 移除掉(因为追加的时候去重了,所以删除一次就够了,不需要在向后找了)
// 为了防止数组塌陷,此处不使用 splice(i, 1) 删除,使用 null 赋值即可
pondT[i] = null;
return;
}
}
}
// 通知事件池中某个类型对应的方法依次执行
// ...args <=> [].slice.call(arguements,1)
$emit(type, ...args) {
let pondT = this.pond[type] || [];
for (let i = 0; i < pondT.length; i++) {
let func = pondT[i];
// 如果不是函数,在容器中移除掉
if (typeof func !== "function") {
pondT.splice(i, 1);
// 因为执行了 splice 导致数组塌陷,导致后面的元素索引全部 -1,让 i 也减 1
i--;
continue;
}
func.apply(this, args);
}
}
}
window.EB = new EventBus();
})();
<!-- 测试 -->
<script>
function fn1() { console.log(1); }
function fn2() { console.log(2); }
function fn3() {
console.log(3);
EB.$off('AA', fn1);
EB.$off('AA', fn2);
}
function fn4() { console.log(4); }
function fn5() { console.log(5); }
function fn6() { console.log(6); }
EB.$on('AA', fn1);
EB.$on('AA', fn2);
EB.$on('AA', fn3);
EB.$on('AA', fn4);
EB.$on('AA', fn5);
EB.$on('AA', fn6);
</script>
应用
- 更好的管理项目中的代码,方便维护,方便团队协作,方便扩展…;
- 基于发布订阅模式管控,用户登录获取基本信息后逐一需要做的事情;
- 双向数据绑定;
打赏作者
您的打赏是我前进的动力
微信
支付宝
剑指 Offer 47.礼物的最大价值
上一篇
评论