当前位置:首页 > JavaScript

js eventbus实现

2026-04-06 07:56:08JavaScript

实现 EventBus 的基本结构

EventBus 的核心是一个事件订阅和发布的机制,通常包含 onoffemit 方法。以下是一个基础实现:

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

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

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

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

支持一次性事件监听

扩展 EventBus 以支持一次性事件监听(once 方法):

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

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

  // 保留之前的 on、off、emit 方法
}

支持异步事件处理

为事件处理添加异步支持,允许使用 async/await

class EventBus {
  async emitAsync(eventName, ...args) {
    if (!this.events[eventName]) return;
    const promises = this.events[eventName].map((callback) =>
      callback(...args)
    );
    return Promise.all(promises);
  }
}

添加事件命名空间

支持事件命名空间,避免事件名称冲突:

class EventBus {
  on(namespace, eventName, callback) {
    const fullEventName = `${namespace}:${eventName}`;
    if (!this.events[fullEventName]) {
      this.events[fullEventName] = [];
    }
    this.events[fullEventName].push(callback);
  }

  emit(namespace, eventName, ...args) {
    const fullEventName = `${namespace}:${eventName}`;
    if (!this.events[fullEventName]) return;
    this.events[fullEventName].forEach((callback) => {
      callback(...args);
    });
  }
}

错误处理和调试

添加错误处理和调试信息,方便排查问题:

class EventBus {
  emit(eventName, ...args) {
    if (!this.events[eventName]) {
      console.warn(`Event "${eventName}" has no listeners.`);
      return;
    }
    this.events[eventName].forEach((callback) => {
      try {
        callback(...args);
      } catch (error) {
        console.error(`Error in event "${eventName}":`, error);
      }
    });
  }
}

完整实现示例

结合以上功能,以下是一个完整的 EventBus 实现:

js eventbus实现

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

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

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

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

  emit(eventName, ...args) {
    if (!this.events[eventName]) {
      console.warn(`Event "${eventName}" has no listeners.`);
      return;
    }
    this.events[eventName].forEach((callback) => {
      try {
        callback(...args);
      } catch (error) {
        console.error(`Error in event "${eventName}":`, error);
      }
    });
  }

  async emitAsync(eventName, ...args) {
    if (!this.events[eventName]) return;
    const promises = this.events[eventName].map((callback) =>
      callback(...args)
    );
    return Promise.all(promises);
  }
}

使用示例

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}!`);
});
bus.emit('greet', 'Alice'); // 触发
bus.emit('greet', 'Bob');   // 不触发

// 异步事件
bus.on('fetch', async (url) => {
  const response = await fetch(url);
  console.log(await response.json());
});
bus.emitAsync('fetch', 'https://api.example.com/data');

标签: jseventbus
分享给朋友:

相关文章

css3结合js制作

css3结合js制作

CSS3 结合 JavaScript 制作动态效果 CSS3 和 JavaScript 结合可以实现丰富的动态效果,包括动画、交互和响应式设计。以下是几种常见的实现方式: CSS3 动画与 Java…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1; le…

js实现菜单

js实现菜单

实现基本HTML结构 使用HTML创建菜单的基本框架,通常包含<ul>和<li>元素。示例结构如下: <ul id="menu"> <li><…

js实现弹框

js实现弹框

使用 alert 实现简单弹框 JavaScript 的 alert 方法可以直接显示一个简单的弹框,内容为纯文本: alert("这是一个简单的弹框"); 使用 confirm 实现确认弹框…