订 阅 模 式

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();

猜你喜欢

转载自blog.csdn.net/Stark6/article/details/120042188