订 阅 模 式

这是一个关于JavaScript事件订阅和发布的实现。代码定义了一个`Subscription`类,它包含`eventList`和`offLineList`两个属性,用于存储事件和回调。`on`方法用于订阅事件,`once`用于一次性订阅,`off`用于取消订阅,`emit`则用于触发事件。当事件触发时,如果对应回调列表为空,则事件会被缓存,待组件加载完成后派发。
摘要由CSDN通过智能技术生成
class Subscription {
  #eventList = new Map();
  #offLineList = new Map();

  on(eventName, eventCallback, once = false) {
    const list = this.#eventList.get(eventName) || [];
    list.push({ eventCallback, once });
    this.#eventList.set(eventName, list);

    // 派发之前缓存的队列
    const offLineIndex = this.#offLineList.get(eventName) || 0;
    for (let i = 0; i < offLineIndex.length; i++) {
      this.emit(eventName);
    }
    this.#offLineList.delete(eventName);
  }

  once(eventName, eventCallback) {
    this.on(eventName, eventCallback, true);
  }

  off(eventName, eventCallback) {
    if (!this.#eventList.has(eventName)) {
      throw new Error("该事件并没有发布过订阅!");
    }

    if (!eventCallback) {
      this.#eventList.delete(eventName);
      return;
    }

    const list = this.#eventList.get(eventName);
    const filerList = list.filter((a) => a !== eventCallback);
    this.#eventList.set(eventName, filerList);
  }

  emit(eventName) {
    if (!this.#eventList.has(eventName)) {
      throw new Error("该事件并没有发布过订阅!");
    }

    const list = this.#eventList.get(eventName);

    // 异步组件还未加载完成,缓存队列
    if (!list.length) {
      const i = this.#offLineList.get(eventName) || 0;
      this.#offLineList.set(eventName, i++);
      return;
    }

    const filerList = list.filter(({ eventCallback, once }) => {
      eventCallback();
      return !once;
    });
    this.#eventList.set(eventName, filerList);
  }
}

const subscription = new Subscription();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值