当前位置:首页 > 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 方法:

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

支持事件优先级

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

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 可以这样实现:

js 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
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 实现页面跳转,这是最常用的方法。 window.location.href = 'https://…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('image…

jquery js

jquery js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够更高…

js jquery

js jquery

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。 &…

js实现授权

js实现授权

授权流程设计 授权流程通常涉及前端与后端的交互,常见方案包括OAuth2.0、JWT等。以JWT为例的典型流程: 用户提交凭证(如用户名密码)到认证服务 服务端验证通过后生成包含用户信息的JWT令牌…