Skip to content

EventEmitter

事件发布订阅模式实现,提供事件监听器的注册、触发和移除功能。

前置依赖

依赖参数

参数名类型说明
deps.logConsole['log']日志输出函数
deps.errorConsole['error']错误日志函数
deps.warnConsole['warn']警告日志函数

环境要求

  • console: 控制台对象(浏览器或 Node.js 均可用)
typescript
const deps = {
  log: console.log,
  error: console.error,
  warn: console.warn
}

函数签名

typescript
function createEventEmitter(
  deps: EventEmitterDeps,
  options?: EventEmitterOptions
): EventEmitter

class EventEmitter {
  on(event: string, listener: EventListener): this
  once(event: string, listener: EventListener): this
  off(event: string, listener?: EventListener): this
  emit(event: string, ...args: any[]): boolean
  listeners(event: string): EventListener[]
  listenerCount(event: string): number
  eventNames(): string[]
  removeAllListeners(event?: string): this
  setMaxListeners(n: number): this
  getMaxListeners(): number
}

type EventListener = (...args: any[]) => void

interface EventEmitterDeps {
  log: Console['log']
  error: Console['error']
  warn: Console['warn']
}

interface EventEmitterOptions {
  maxListeners?: number  // 单个事件最大监听器数量,默认 10
}

参数

参数名类型必填默认值说明
depsEventEmitterDeps-依赖注入对象
options.maxListenersnumber10单个事件的最大监听器数量

返回值

类型说明
EventEmitterEventEmitter 实例

工作原理

  1. 事件存储

    • 使用 Map 存储事件和监听器列表
    • 键为事件名,值为监听器数组
  2. on(event, listener)

    • 将监听器添加到事件的监听器数组
    • 检查是否超过 maxListeners 限制
    • 返回 this(支持链式调用)
  3. once(event, listener)

    • 创建包装函数,执行后自动移除
    • 将包装函数注册为监听器
    • 返回 this
  4. emit(event, ...args)

    • 获取事件的所有监听器
    • 依次调用每个监听器,传入参数
    • 使用 try-catch 隔离错误(防止一个监听器错误影响其他)
    • 返回是否有监听器被调用
  5. off(event, listener)

    • 如果提供 listener:移除指定监听器
    • 如果不提供:移除该事件的所有监听器
    • 返回 this
  6. 内存泄漏检测

    • 当监听器数量超过 maxListeners 时,输出警告
    • 提示可能的内存泄漏

经典的发布订阅模式实现,类似 Node.js Events 模块。