JavaScript 发布-订阅实现

129 阅读1分钟

一个全局的 “发布-订阅” 事件机制,以便于层次关系不明确的组件间的直接通信.

Code

  • EventBox.js
// 简单实现一个 “发布-订阅” 事件池类

export default class EventBox {
    handlers = {}

    emit = (event, ...payload) => {
      const handlers = this.handlers[event];
      if (!handlers || !handlers.length) {
        return;
      }

      const count = handlers.length;

      for (let i = 0; i < count; i++) {
        const handler = handlers[i];
        if (typeof handler === 'function') {
          handler(...payload);
        }
      }
    }

    on = (event, handler) => {
      if (!this.handlers[event]) {
        this.handlers[event] = [];
      }

      this.handlers[event].push(handler);

      const off = () => {
        this.off(event, handler);
      };

      return {
        off,
        remove: off,
      };
    }

    off = (event, handler) => {
      const handlers = this.handlers[event];
      if (!handlers || !handlers.length) {
        return;
      }

      for (let i = handlers.length; i-- > 0;) {
        if (handler === handlers[i]) {
          console.log(`remove ${event}`);
          handlers.splice(i, 1);
        }
      }
    }
}

  • index.js
import EventBox from './EventBox'

const globalEvents = new EventBox()

export const on = globalEvents.on
export const off = globalEvents.off
export const emit = globalEvents.emit

export default globalEvents

Usage

 import eventBox from './event-box';

 // bindEvent
 let menuDidUpdateHandler = eventBox.on('didUpdateEvent', () => {
    adaptDocHeight(); // some funs
  });

 // removeEvent
 if (menuDidUpdateHandler) {
    menuDidUpdateHandler.off();
 }