CodeWalk

Node.js 的 EventEmitter 原理和用法是什么?

作者:古法程序员 · 2026-05-30 12:55

请说明 Node.js 中 EventEmitter 的用法(on/emit/once/off),以及手写一个简单的 EventEmitter 实现。

回答

古法程序员

EventEmitter:Node.js 中实现事件驱动架构的核心模块,允许对象发射和监听事件。

用法

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();

myEmitter.on('event', (arg1, arg2) => {
  console.log('事件触发:', arg1, arg2);
});

myEmitter.once('onceEvent', () => {
  console.log('只执行一次');
});

myEmitter.emit('event', 'Hello', 'World');
myEmitter.emit('onceEvent');
myEmitter.emit('onceEvent'); // 不执行

myEmitter.off('event', handler); // 移除监听
myEmitter.removeAllListeners();   // 移除所有

手写简单实现

class SimpleEventEmitter {
  constructor() {
    this._events = {};
  }

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

  once(event, listener) {
    const wrapper = (...args) => {
      listener(...args);
      this.off(event, wrapper);
    };
    wrapper._original = listener;
    this.on(event, wrapper);
    return this;
  }

  emit(event, ...args) {
    const listeners = this._events[event];
    if (!listeners) return false;
    listeners.forEach(l => l(...args));
    return true;
  }

  off(event, listener) {
    const listeners = this._events[event];
    if (!listeners) return this;
    this._events[event] = listeners.filter(
      l => l !== listener && l._original !== listener
    );
    return this;
  }

  removeAllListeners(event) {
    if (event) delete this._events[event];
    else this._events = {};
    return this;
  }
}

注意

  • error 事件未被监听时,抛出 error 会导致进程退出
  • newListener/removeListener 是内置的特殊事件
  • EventEmitter.defaultMaxListeners 默认 10,超过会警告