当前位置:首页 > 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实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js实现pdf在线预览

js实现pdf在线预览

使用PDF.js实现PDF在线预览 PDF.js是由Mozilla开发的一个开源JavaScript库,可以在网页中直接渲染PDF文件。以下是实现PDF在线预览的步骤: 引入PDF.js库 在HT…

js实现报表

js实现报表

使用JavaScript实现报表 在JavaScript中实现报表功能可以通过多种方式完成,常见的方法包括使用原生JavaScript、第三方库(如Chart.js、D3.js)或结合后端数据渲染。以…

js实现dh

js实现dh

JavaScript 实现 DH(Diffie-Hellman)密钥交换 Diffie-Hellman(DH)密钥交换是一种安全协议,允许双方在不安全的通信信道上建立一个共享密钥。以下是如何在 Jav…

js实现授权

js实现授权

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

js实现交换

js实现交换

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