class Sub {
events = {};
on(type, func) {
!Array.isArray(this.events[type]) ? (this.events[type] = []) : null;
let arr = this.events[type];
if (arr.includes(func)) return;
arr.push(func);
}
off(type, func) {
let arr = this.events[type];
let item = null;
if (!Array.isArray(this.events[type])) {
throw new TypeError(`${type} 自定义事件在事件池中并不存在!`);
}
for (let i = 0; i < arr.length; i++) {
item = arr[i];
if (item === func) {
// 这样只是让集合中当前项值变为null,但是集合的机构是不发生改变的「索引不变」;
// 下一次执行emit的时候,遇到当前项是null,我们再去把其移除掉即可;
arr[i] = null;
break;
}
}
}
emit(type, ...params) {
let arr = this.events[type];
let item = null;
for (let i = 0; i < arr.length; i++) {
item = arr[i];
if (typeof item === "function") {
item(...params);
continue;
}
//不是函数的值都移除掉即可
arr.splice(i, 1);
i--;
}
}
}
const sub = new Sub();
const fn1 = () => console.log(1);
const fn2 = () => console.log(2);
const fn3 = () => {
console.log(3);
sub.off("A", fn1);
sub.off("A", fn2);
};
const fn4 = () => console.log(4);
const fn5 = () => console.log(5);
const fn6 = () => console.log(6);
sub.on("A", fn1);
// sub.on("A", fn1);
sub.on("A", fn2);
sub.on("A", fn3);
sub.on("A", fn4);
sub.on("A", fn5);
sub.on("A", fn6);
setTimeout(() => {
sub.emit("A");
}, 1000);
setTimeout(() => {
sub.emit("A");
}, 2000);
手写发布订阅类
最新推荐文章于 2024-06-29 09:12:01 发布
本文介绍了一个名为Sub的类,它使用事件驱动设计模式,提供on、off和emit方法来管理自定义事件。on方法注册回调,off方法移除指定事件的回调,emit则触发事件并执行相应函数。示例展示了如何在setTimeout中发送事件并控制回调执行。
361

被折叠的 条评论
为什么被折叠?



