EventBus和EventEmitter

565 阅读3分钟

EventBus

class EventBus {
  constructor() {
    this.events = {}; // 存储事件及其对应的回调函数列表
  }

  // 订阅事件
  subscribe(eventName, callback) {
    this.events[eventName] = this.events[eventName] || []; // 如果事件不存在,创建一个空的回调函数列表
    this.events[eventName].push(callback); // 将回调函数添加到事件的回调函数列表中
  }

  // 发布事件
  publish(eventName, data) {
    if (this.events[eventName]) {
     this.events[eventName].forEach(callback => {
        callback(data); // 执行回调函数,并传递数据作为参数
      });
    }
  }

  // 取消订阅事件
  unsubscribe(eventName, callback) {
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(cb => cb !== callback); // 过滤掉要取消的回调函数
    }
  }
}

EventEmitter

class EventEmitter {
  constructor() {
    this.events = {}; // 用于存储事件及其对应的回调函数列表
  }

  // 订阅事件
  on(eventName, callback) {
    this.events[eventName] = this.events[eventName] || []; // 如果事件不存在,创建一个空的回调函数列表
    this.events[eventName].push(callback); // 将回调函数添加到事件的回调函数列表中
  }

  // 发布事件
  emit(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(callback => {
        callback(data); // 执行回调函数,并传递数据作为参数
      });
    }
  }

  // 取消订阅事件
  off(eventName, callback) {
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(cb => cb !== callback); // 过滤掉要取消的回调函数
    }
  }
  
  // 添加一次性的事件监听器 
  once(eventName, callback) { 
      const onceCallback = data => { 
          callback(data); // 执行回调函数 
          this.off(eventName, onceCallback); // 在执行后取消订阅该事件 
      }; 
      this.on(eventName, onceCallback); 
  }
}

eventBus,eventEmitter的区别

EventBusEventEmitter 都是用于实现事件发布-订阅模式的工具,但它们在实现和使用上有一些区别。

  1. 实现方式:

    • EventBusEventBus 是一个全局的事件总线,通常是作为一个单例对象存在,用于在不同组件或模块之间传递事件和数据。在 Vue.js 中,Vue 实例可以充当 EventBus 的角色。
    • EventEmitterEventEmitter 是一个基于类的模块,通常是作为一个实例对象存在,用于在单个组件或模块内部实现事件的发布和订阅。
  2. 使用范围:

    • EventBusEventBus 的作用范围更广泛,可以跨越不同组件、模块或文件进行事件的发布和订阅。它可以实现多个组件之间的通信和数据传递。
    • EventEmitterEventEmitter 主要用于单个组件或模块内部,用于实现内部事件的处理和通信。
  3. 依赖关系:

    • EventBusEventBus 通常需要一个中央管理的实例,因此需要在应用程序的某个地方进行创建和管理。在 Vue.js 中,Vue 实例可以用作全局的 EventBus
    • EventEmitterEventEmitter 可以在需要的地方创建实例对象,并将其用于内部事件的发布和订阅。
  4. 命名空间:

    • EventBusEventBus 可以使用不同的事件名称来进行事件的区分和分类,可以使用命名空间来标识不同类型的事件。
    • EventEmitterEventEmitter 通常使用字符串作为事件的名称,没有直接支持命名空间的概念。

总结起来,EventBus 主要用于实现跨组件或模块的事件通信和数据传递,适用于大型应用程序;而 EventEmitter 主要用于组件或模块内部的事件处理和通信,适用于小型应用程序或组件级别的事件管理。选择使用哪种工具取决于你的具体需求和应用场景。

转自:juejin.cn/post/724075…