当前位置:首页 > JavaScript

js eventbus实现

2026-02-01 15:07:30JavaScript

实现 EventBus 的基本结构

EventBus 是一种发布/订阅模式,用于组件或模块间的通信。以下是一个简单的 EventBus 实现:

class EventBus {
  constructor() {
    this.events = {};
  }

  on(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(callback);
  }

  emit(eventName, ...args) {
    const callbacks = this.events[eventName];
    if (callbacks) {
      callbacks.forEach(callback => callback(...args));
    }
  }

  off(eventName, callback) {
    const callbacks = this.events[eventName];
    if (callbacks) {
      this.events[eventName] = callbacks.filter(cb => cb !== callback);
    }
  }

  once(eventName, callback) {
    const wrapper = (...args) => {
      callback(...args);
      this.off(eventName, wrapper);
    };
    this.on(eventName, wrapper);
  }
}

使用示例

const bus = new EventBus();

// 订阅事件
bus.on('message', (text) => {
  console.log(`Received: ${text}`);
});

// 发布事件
bus.emit('message', 'Hello EventBus!');

// 一次性订阅
bus.once('greet', (name) => {
  console.log(`Hello ${name}, this will only fire once!`);
});

bus.emit('greet', 'Alice'); // 触发
bus.emit('greet', 'Bob');   // 不触发

// 取消订阅
const handler = (data) => console.log(data);
bus.on('data', handler);
bus.off('data', handler);

支持异步事件处理

如果需要支持异步事件处理,可以修改 emit 方法:

js eventbus实现

async emitAsync(eventName, ...args) {
  const callbacks = this.events[eventName];
  if (callbacks) {
    for (const callback of callbacks) {
      await callback(...args);
    }
  }
}

支持事件优先级

可以通过扩展实现带优先级的事件监听:

js eventbus实现

on(eventName, callback, priority = 0) {
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  }
  this.events[eventName].push({ callback, priority });
  this.events[eventName].sort((a, b) => b.priority - a.priority);
}

emit(eventName, ...args) {
  const callbacks = this.events[eventName];
  if (callbacks) {
    callbacks.forEach(item => item.callback(...args));
  }
}

防止内存泄漏

在大型应用中,建议添加清除机制:

clear() {
  this.events = {};
}

在 Vue 中的使用

Vue 本身提供了 $emit$on 方法,但全局 EventBus 可以这样实现:

// eventBus.js
import Vue from 'vue';
export default new Vue();

// 组件A
import eventBus from './eventBus';
eventBus.$on('event', handler);

// 组件B
import eventBus from './eventBus';
eventBus.$emit('event', data);

注意事项

  • 避免过度使用全局 EventBus,可能导致难以追踪的事件流
  • 及时清理无用的事件监听,防止内存泄漏
  • 考虑使用 TypeScript 添加类型支持,提高代码健壮性

标签: jseventbus
分享给朋友:

相关文章

eventbus实现原理vue

eventbus实现原理vue

EventBus 的实现原理(Vue) EventBus 是 Vue 中实现跨组件通信的一种简单机制,其核心原理基于发布-订阅模式(Pub-Sub)。以下是其实现的关键点: 核心机制 事件中心 E…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

vue实现eventbus

vue实现eventbus

Vue 2 中实现 EventBus 在 Vue 2 中,可以通过创建一个新的 Vue 实例作为事件总线来实现组件间的通信。这种方式适用于非父子组件或跨层级组件通信。 创建一个单独的 event-b…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js手势实现

js手势实现

手势识别实现方法 在JavaScript中实现手势识别通常涉及监听触摸事件(touchstart、touchmove、touchend)或鼠标事件(mousedown、mousemove、mouseu…