手写javascript发布订阅系统

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发布订阅系统

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. 遍历执行所有绑定函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值