当前位置:首页 > JavaScript

js实现eventemitter

2026-03-14 03:06:16JavaScript

实现 EventEmitter 的基本结构

EventEmitter 是 Node.js 的核心模块之一,用于实现事件订阅与发布模式。在 JavaScript 中可以通过类或构造函数实现类似功能。

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

添加事件监听方法

实现 on 方法用于订阅事件,支持多个回调函数。

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

触发事件方法

实现 emit 方法用于触发事件,执行所有注册的回调函数。

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

移除事件监听

实现 off 方法用于取消事件监听。

js实现eventemitter

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

一次性事件监听

实现 once 方法用于只触发一次的事件监听。

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

完整实现代码

将所有方法组合起来形成完整的 EventEmitter 实现。

js实现eventemitter

class EventEmitter {
  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);
  }
}

使用示例

展示如何在实际代码中使用自定义的 EventEmitter。

const emitter = new EventEmitter();

// 添加监听
emitter.on('message', (msg) => {
  console.log('收到消息:', msg);
});

// 触发事件
emitter.emit('message', 'Hello World');

// 一次性监听
emitter.once('greet', (name) => {
  console.log(`Hello ${name}`);
});

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

// 移除监听
const handler = (data) => console.log('Data:', data);
emitter.on('data', handler);
emitter.off('data', handler);

错误处理增强

为 EventEmitter 添加错误处理机制,避免未处理的错误导致程序崩溃。

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

最大监听数限制

实现监听器数量的限制,防止内存泄漏。

constructor(maxListeners = 10) {
  this.events = {};
  this.maxListeners = maxListeners;
}

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

  if (this.events[eventName].length >= this.maxListeners) {
    console.warn(`Possible memory leak detected for event "${eventName}"`);
  }

  this.events[eventName].push(callback);
}

标签: jseventemitter
分享给朋友:

相关文章

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js 进度条的实现

js 进度条的实现

使用 HTML 和 CSS 创建基础进度条 HTML 结构可以简单使用一个 div 元素作为容器,内部嵌套另一个 div 表示进度: <div class="progress-containe…

js实现复制功能

js实现复制功能

使用 document.execCommand 方法 这种方法适用于较旧的浏览器,但在现代浏览器中可能被逐步淘汰。通过创建一个临时的 textarea 元素,将文本内容放入其中,然后执行复制命令。…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…