当前位置:首页 > JavaScript

js实现eventemitter

2026-02-01 04:49:35JavaScript

实现 EventEmitter 的基本结构

EventEmitter 是一种观察者模式的实现,允许对象订阅和触发自定义事件。以下是一个基本的实现框架:

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

添加事件监听方法

实现 on 方法用于添加事件监听器:

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

触发事件方法

实现 emit 方法用于触发事件:

emit(eventName, ...args) {
  const listeners = this.events[eventName];
  if (listeners) {
    listeners.forEach(listener => {
      listener.apply(this, args);
    });
  }
  return this;
}

移除事件监听器

实现 off 方法用于移除事件监听器:

off(eventName, listenerToRemove) {
  const listeners = this.events[eventName];
  if (listeners) {
    this.events[eventName] = listeners.filter(
      listener => listener !== listenerToRemove
    );
  }
  return this;
}

一次性事件监听器

实现 once 方法用于添加只触发一次的事件监听器:

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

完整实现示例

将所有方法组合起来的完整实现:

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

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

  emit(eventName, ...args) {
    const listeners = this.events[eventName];
    if (listeners) {
      listeners.forEach(listener => {
        listener.apply(this, args);
      });
    }
    return this;
  }

  off(eventName, listenerToRemove) {
    const listeners = this.events[eventName];
    if (listeners) {
      this.events[eventName] = listeners.filter(
        listener => listener !== listenerToRemove
      );
    }
    return this;
  }

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

使用示例

const emitter = new EventEmitter();

// 添加常规监听器
const helloListener = (name) => {
  console.log(`Hello ${name}`);
};
emitter.on('greet', helloListener);

// 添加一次性监听器
emitter.once('greet', (name) => {
  console.log(`First time greeting ${name}`);
});

// 触发事件
emitter.emit('greet', 'Alice');  // 输出: Hello Alice 和 First time greeting Alice
emitter.emit('greet', 'Bob');    // 只输出: Hello Bob

// 移除监听器
emitter.off('greet', helloListener);
emitter.emit('greet', 'Charlie'); // 无输出

性能优化考虑

对于高频触发的事件,可以考虑以下优化措施:

// 在构造函数中添加
this.maxListeners = 10;

// 在on方法中添加警告
on(eventName, listener) {
  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(listener);
  return this;
}

错误处理增强

可以为事件监听器添加错误处理机制:

js实现eventemitter

emit(eventName, ...args) {
  const listeners = this.events[eventName];
  if (listeners) {
    listeners.forEach(listener => {
      try {
        listener.apply(this, args);
      } catch (err) {
        if (this.events['error']) {
          this.emit('error', err);
        } else {
          console.error('Unhandled error in event listener:', err);
        }
      }
    });
  }
  return this;
}

标签: jseventemitter
分享给朋友:

相关文章

js实现继承

js实现继承

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

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

jquery.js

jquery.js

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互等操作。以下是关于 jQuery.js 的核心信息和使用方法: 获…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统的…

js 实现链表

js 实现链表

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

js画图实现

js画图实现

使用Canvas API绘制图形 Canvas是HTML5提供的绘图API,通过JavaScript操作Canvas元素可以绘制各种图形。以下是一个简单的示例: <canvas id="myC…