手写javascript发布订阅系统

本文详细介绍了一个名为EventCenter的类,它提供了一套完整的事件发布、订阅、解除绑定和仅触发一次的机制。通过实例演示,展示了如何使用这个系统来管理事件并确保数据更新的精确性。

发布订阅系统

class EventCenter {
  eventList = new Map(); // 1
  // 绑定
  on(name, fn) {
    let eventInfo = this.eventList.get(name);
    if (!eventInfo) { // 2
      eventInfo = {
        data: {},
        callback: new Set(),
      };
      this.eventList.set(name, eventInfo); // 3
    }
    eventInfo.callback.add(fn); // 4
  }
  // 解除绑定
  off(name, fn) {
    let eventInfo = this.eventList.get(name);
    if (eventInfo && typeof fn === "function") { // 5
      eventInfo.callback.delete(name);
    }
  }
  // 只执行一次的订阅事件
  once(name,fn) {
	let newFn = (...args) => {
      fn(...args);
      this.off(name, newFn);
    };
    this.on(name, newFn);
  }
  // 发送数据
  dispatch(name, data) {
    let eventInfo = this.eventList.get(name);
    if (eventInfo && eventInfo.data !== data) { // 6
      eventInfo.data = data;
      for (const f of eventInfo.callback) { // 7
        f(data);
      }
    }
  }
}
// 测试数据
const eventCenter = new EventCenter();
let fn = (data) => {
  console.log(data);
};
eventCenter.on("test", fn);
eventCenter.dispatch("test", "测试数据1"); // 打印:测试数据1
eventCenter.dispatch("test", "测试数据1"); // 和前一次的数据相同不会触发事件
eventCenter.dispatch("test", "测试数据3"); // 打印:测试数据3
eventCenter.off("test", fn);
eventCenter.dispatch("test", "测试数据4"); // 已经解除监听,不会打印

eventCenter.once("once", fn);
eventCenter.dispatch("once", "测试只会触发一次1"); // 打印:测试只会触发一次1
eventCenter.dispatch("once", "测试只会触发一次2"); // 已经触发过一次,这里不会再次打印

详细过程描述

  1. 缓存数据和绑定函数
  2. 如果没有缓存则初始化
  3. 放入缓存中
  4. 记录绑定函数
  5. eventInfo存在且fn为函数则卸载指定函数
  6. 当数据不相等时才更新
  7. 遍历执行所有绑定函数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值