Skip to content

事件

[稳定: 2 - 稳定]

稳定: 2 稳定性: 2 - 稳定

源代码: lib/events.js

许多 Node.js 核心 API 都是围绕着一种惯用的异步事件驱动架构构建的,在这种架构中,某些类型的对象(称为“发射器”)会发出命名事件,从而导致 Function 对象(“监听器”)被调用。

例如:每次对等体连接到 net.Server 对象时,它都会发出一个事件;当文件打开时,fs.ReadStream 会发出一个事件; 在有数据可供读取时会发出一个事件。

所有发出事件的对象都是 EventEmitter 类的实例。这些对象公开了一个 eventEmitter.on() 函数,该函数允许将一个或多个函数附加到对象发出的命名事件。通常,事件名称是小驼峰式字符串,但可以使用任何有效的 JavaScript 属性键。

EventEmitter 对象发出事件时,附加到该特定事件的所有函数都会同步调用。调用监听器返回的任何值都会被忽略并丢弃。

以下示例显示了一个带有单个监听器的简单 EventEmitter 实例。eventEmitter.on() 方法用于注册监听器,而 eventEmitter.emit() 方法用于触发事件。

js
import { EventEmitter } from 'node:events'

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('an event occurred!')
})
myEmitter.emit('event')
js
const EventEmitter = require('node:events')

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
myEmitter.on('event', () => {
  console.log('an event occurred!')
})
myEmitter.emit('event')

向监听器传递参数和 this

eventEmitter.emit() 方法允许将任意数量的参数传递给监听器函数。请记住,当调用普通监听器函数时,标准的 this 关键字有意设置为引用监听器所附加的 EventEmitter 实例。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', function (a, b) {
  console.log(a, b, this, this === myEmitter)
  // 打印:
  //   a b MyEmitter {
  //     _events: [Object: null prototype] { event: [Function (anonymous)] },
  //     _eventsCount: 1,
  //     _maxListeners: undefined,
  //     [Symbol(shapeMode)]: false,
  //     [Symbol(kCapture)]: false
  //   } true
})
myEmitter.emit('event', 'a', 'b')
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', function (a, b) {
  console.log(a, b, this, this === myEmitter)
  // 打印:
  //   a b MyEmitter {
  //     _events: [Object: null prototype] { event: [Function (anonymous)] },
  //     _eventsCount: 1,
  //     _maxListeners: undefined,
  //     [Symbol(shapeMode)]: false,
  //     [Symbol(kCapture)]: false
  //   } true
})
myEmitter.emit('event', 'a', 'b')

可以使用 ES6 箭头函数作为监听器,但是,这样做时,this 关键字将不再引用 EventEmitter 实例:

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  console.log(a, b, this)
  // 打印:a b undefined
})
myEmitter.emit('event', 'a', 'b')
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  console.log(a, b, this)
  // 打印:a b {}
})
myEmitter.emit('event', 'a', 'b')

异步与同步

EventEmitter 以注册顺序同步调用所有监听器。这确保了事件的正确排序,并有助于避免竞争条件和逻辑错误。在适当的情况下,监听器函数可以使用 setImmediate()process.nextTick() 方法切换到异步操作模式:

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('this happens asynchronously')
  })
})
myEmitter.emit('event', 'a', 'b')
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('this happens asynchronously')
  })
})
myEmitter.emit('event', 'a', 'b')

只处理一次事件

当使用 eventEmitter.on() 方法注册监听器时,每次发出命名事件时都会调用该监听器。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.on('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// 打印:1
myEmitter.emit('event')
// 打印:2
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.on('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// 打印:1
myEmitter.emit('event')
// 打印:2

使用 eventEmitter.once() 方法,可以注册一个监听器,该监听器对于特定事件最多只调用一次。一旦发出事件,监听器就会注销,然后被调用。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.once('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// 打印:1
myEmitter.emit('event')
// 被忽略
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
let m = 0
myEmitter.once('event', () => {
  console.log(++m)
})
myEmitter.emit('event')
// 打印:1
myEmitter.emit('event')
// 被忽略

错误事件

EventEmitter 实例中发生错误时,通常会发出 'error' 事件。这些事件在 Node.js 中被视为特殊情况。

如果 EventEmitter 没有为 'error' 事件注册至少一个监听器,并且发出了 'error' 事件,则会抛出错误,打印堆栈跟踪,并且 Node.js 进程退出。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('whoops!'))
// 抛出错误并使 Node.js 崩溃
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.emit('error', new Error('whoops!'))
// 抛出错误并使 Node.js 崩溃

为了防止 Node.js 进程崩溃,可以使用 domain 模块。(但是,请注意,node:domain 模块已弃用。)

最佳实践是始终为 'error' 事件添加监听器。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('error', err => {
  console.error('whoops! there was an error')
})
myEmitter.emit('error', new Error('whoops!'))
// 打印:whoops! there was an error
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('error', err => {
  console.error('whoops! there was an error')
})
myEmitter.emit('error', new Error('whoops!'))
// 打印:whoops! there was an error

可以使用符号 events.errorMonitor 安装监听器来监控 'error' 事件,而不会使用已发出的错误。

js
import { EventEmitter, errorMonitor } from 'node:events'

const myEmitter = new EventEmitter()
myEmitter.on(errorMonitor, err => {
  MyMonitoringTool.log(err)
})
myEmitter.emit('error', new Error('whoops!'))
// 仍然抛出错误并使 Node.js 崩溃
js
const { EventEmitter, errorMonitor } = require('node:events')

const myEmitter = new EventEmitter()
myEmitter.on(errorMonitor, err => {
  MyMonitoringTool.log(err)
})
myEmitter.emit('error', new Error('whoops!'))
// 仍然抛出错误并使 Node.js 崩溃

捕获 Promise 的拒绝

在事件处理程序中使用 async 函数是有问题的,因为如果抛出异常,可能会导致未处理的拒绝:

js
import { EventEmitter } from 'node:events'
const ee = new EventEmitter()
ee.on('something', async value => {
  throw new Error('kaboom')
})
js
const EventEmitter = require('node:events')
const ee = new EventEmitter()
ee.on('something', async value => {
  throw new Error('kaboom')
})

EventEmitter 构造函数中的 captureRejections 选项或全局设置会改变此行为,在 Promise 上安装 .then(undefined, handler) 处理程序。如果存在,此处理程序会异步地将异常路由到 Symbol.for('nodejs.rejection') 方法,否则路由到 'error' 事件处理程序。

js
import { EventEmitter } from 'node:events'
const ee1 = new EventEmitter({ captureRejections: true })
ee1.on('something', async value => {
  throw new Error('kaboom')
})

ee1.on('error', console.log)

const ee2 = new EventEmitter({ captureRejections: true })
ee2.on('something', async value => {
  throw new Error('kaboom')
})

ee2[Symbol.for('nodejs.rejection')] = console.log
js
const EventEmitter = require('node:events')
const ee1 = new EventEmitter({ captureRejections: true })
ee1.on('something', async value => {
  throw new Error('kaboom')
})

ee1.on('error', console.log)

const ee2 = new EventEmitter({ captureRejections: true })
ee2.on('something', async value => {
  throw new Error('kaboom')
})

ee2[Symbol.for('nodejs.rejection')] = console.log

设置 events.captureRejections = true 将更改所有新 EventEmitter 实例的默认值。

js
import { EventEmitter } from 'node:events'

EventEmitter.captureRejections = true
const ee1 = new EventEmitter()
ee1.on('something', async value => {
  throw new Error('kaboom')
})

ee1.on('error', console.log)
js
const events = require('node:events')
events.captureRejections = true
const ee1 = new events.EventEmitter()
ee1.on('something', async value => {
  throw new Error('kaboom')
})

ee1.on('error', console.log)

captureRejections 行为生成的 'error' 事件没有 catch 处理程序以避免无限错误循环:建议 不要使用async 函数作为'error' 事件处理程序

类: EventEmitter

[历史]

版本变更
v13.4.0, v12.16.0添加了 captureRejections 选项。
v0.1.26在 v0.1.26 中添加

EventEmitter 类由 node:events 模块定义和导出:

js
import { EventEmitter } from 'node:events'
js
const EventEmitter = require('node:events')

所有 EventEmitter 在添加新的监听器时都会发出 'newListener' 事件,在移除现有的监听器时会发出 'removeListener' 事件。

它支持以下选项:

事件: 'newListener'

添加到:v0.1.26

EventEmitter 实例会在监听器添加到其内部监听器数组 之前 发出其自己的 'newListener' 事件。

'newListener' 事件注册的监听器会传递事件名称和对正在添加的监听器的引用。

该事件在添加监听器之前触发这一事实有一个细微但重要的副作用:在 'newListener' 回调中注册到相同 name 的任何 附加 监听器都会在正在添加的监听器 之前 插入。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// 只执行一次,以免无限循环
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // 在前面插入一个新的监听器
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// 打印:
//   B
//   A
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter()
// 只执行一次,以免无限循环
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // 在前面插入一个新的监听器
    myEmitter.on('event', () => {
      console.log('B')
    })
  }
})
myEmitter.on('event', () => {
  console.log('A')
})
myEmitter.emit('event')
// 打印:
//   B
//   A

事件:'removeListener'

[历史]

版本变更
v6.1.0, v4.7.0使用 .once() 附加的监听器,listener 参数现在返回原始监听器函数。
v0.9.3添加于:v0.9.3

'removeListener' 事件在 listener 移除 之后 触发。

emitter.addListener(eventName, listener)

添加于:v0.1.26

emitter.on(eventName, listener) 的别名。

emitter.emit(eventName[, ...args])

新增于:v0.1.26

同步调用为名为 eventName 的事件注册的每个监听器,按照注册顺序进行调用,并将提供的参数传递给每个监听器。

如果事件存在监听器,则返回 true,否则返回 false

js
import { EventEmitter } from 'node:events'
const myEmitter = new EventEmitter()

// 第一个监听器
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! first listener')
})
// 第二个监听器
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`event with parameters ${arg1}, ${arg2} in second listener`)
})
// 第三个监听器
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`event with parameters ${parameters} in third listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// 输出:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener
js
const EventEmitter = require('node:events')
const myEmitter = new EventEmitter()

// 第一个监听器
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! first listener')
})
// 第二个监听器
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`event with parameters ${arg1}, ${arg2} in second listener`)
})
// 第三个监听器
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ')
  console.log(`event with parameters ${parameters} in third listener`)
})

console.log(myEmitter.listeners('event'))

myEmitter.emit('event', 1, 2, 3, 4, 5)

// 输出:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener

emitter.eventNames()

新增于:v6.0.0

返回一个数组,其中列出了发射器已注册监听器的事件。数组中的值是字符串或Symbol

js
import { EventEmitter } from 'node:events'

const myEE = new EventEmitter()
myEE.on('foo', () => {})
myEE.on('bar', () => {})

const sym = Symbol('symbol')
myEE.on(sym, () => {})

console.log(myEE.eventNames())
// 输出: [ 'foo', 'bar', Symbol(symbol) ]
js
const EventEmitter = require('node:events')

const myEE = new EventEmitter()
myEE.on('foo', () => {})
myEE.on('bar', () => {})

const sym = Symbol('symbol')
myEE.on(sym, () => {})

console.log(myEE.eventNames())
// 输出: [ 'foo', 'bar', Symbol(symbol) ]

emitter.getMaxListeners()

新增于:v1.0.0

返回 EventEmitter 的当前最大监听器值,该值由 emitter.setMaxListeners(n) 设置,或者默认为 events.defaultMaxListeners

emitter.listenerCount(eventName[, listener])

[历史]

版本变更
v19.8.0, v18.16.0新增 listener 参数。
v3.2.0首次引入: v3.2.0

返回监听名为 eventName 的事件的监听器数量。如果提供了 listener,则返回该监听器在事件监听器列表中出现的次数。

emitter.listeners(eventName)

[历史]

版本变更
v7.0.0对于使用 .once() 附加的监听器,现在返回原始监听器而不是包装函数。
v0.1.26首次引入: v0.1.26

返回名为 eventName 的事件的监听器数组的副本。

js
server.on('connection', stream => {
  console.log('someone connected!')
})
console.log(util.inspect(server.listeners('connection')))
// 打印: [ [Function] ]

emitter.off(eventName, listener)

新增于: v10.0.0

emitter.removeListener() 的别名。

emitter.on(eventName, listener)

新增于: v0.1.101

listener 函数添加到名为 eventName 的事件的监听器数组的末尾。不会检查 listener 是否已被添加。多次调用传递相同的 eventNamelistener 组合将导致 listener 被多次添加和调用。

js
server.on('connection', stream => {
  console.log('someone connected!')
})

返回 EventEmitter 的引用,以便可以链接调用。

默认情况下,事件监听器按添加顺序调用。可以使用 emitter.prependListener() 方法作为替代方法,将事件监听器添加到监听器数组的开头。

js
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.on('foo', () => console.log('a'))
myEE.prependListener('foo', () => console.log('b'))
myEE.emit('foo')
// 打印:
//   b
//   a
js
const EventEmitter = require('node:events')
const myEE = new EventEmitter()
myEE.on('foo', () => console.log('a'))
myEE.prependListener('foo', () => console.log('b'))
myEE.emit('foo')
// 打印:
//   b
//   a

emitter.once(eventName, listener)

新增于:v0.3.0

为名为 eventName 的事件添加一个一次性 listener 函数。下次触发 eventName 时,此侦听器将被移除然后调用。

js
server.once('connection', stream => {
  console.log('Ah, we have our first user!')
})

返回 EventEmitter 的引用,以便可以链接调用。

默认情况下,事件侦听器按添加顺序调用。emitter.prependOnceListener() 方法可用作替代方法,以将事件侦听器添加到侦听器数组的开头。

js
import { EventEmitter } from 'node:events'
const myEE = new EventEmitter()
myEE.once('foo', () => console.log('a'))
myEE.prependOnceListener('foo', () => console.log('b'))
myEE.emit('foo')
// 打印:
//   b
//   a
js
const EventEmitter = require('node:events')
const myEE = new EventEmitter()
myEE.once('foo', () => console.log('a'))
myEE.prependOnceListener('foo', () => console.log('b'))
myEE.emit('foo')
// 打印:
//   b
//   a

emitter.prependListener(eventName, listener)

新增于:v6.0.0

listener 函数添加到名为 eventName 的事件的监听器数组的 开头。不会检查 listener 是否已被添加。多次调用传递相同的 eventNamelistener 组合将导致 listener 被多次添加和调用。

js
server.prependListener('connection', stream => {
  console.log('someone connected!')
})

返回 EventEmitter 的引用,以便可以链接调用。

emitter.prependOnceListener(eventName, listener)

新增于: v6.0.0

将一个一次性listener 函数添加到名为 eventName 的事件的监听器数组的开头。下次触发 eventName 时,此监听器将被移除,然后调用。

js
server.prependOnceListener('connection', stream => {
  console.log('Ah, we have our first user!')
})

返回 EventEmitter 的引用,以便可以链式调用。

emitter.removeAllListeners([eventName])

新增于: v0.1.26

移除所有监听器,或指定 eventName 的监听器。

移除在代码其他地方添加的监听器是不好的做法,尤其是在 EventEmitter 实例由其他组件或模块(例如套接字或文件流)创建时。

返回 EventEmitter 的引用,以便可以链式调用。

emitter.removeListener(eventName, listener)

新增于:v0.1.26

从名为 eventName 的事件的监听器数组中移除指定的 listener

js
const callback = stream => {
  console.log('someone connected!')
}
server.on('connection', callback)
// ...
server.removeListener('connection', callback)

removeListener() 最多将从监听器数组中移除一个监听器实例。如果任何单个监听器已多次添加到指定 eventName 的监听器数组中,则必须多次调用 removeListener() 以移除每个实例。

一旦事件被发出,所有在发出事件时附加到该事件的监听器都将按顺序被调用。这意味着任何在发出事件之后和最后一个监听器完成执行之前removeListener()removeAllListeners() 调用都不会将它们从正在进行的 emit() 中移除。后续事件的行为符合预期。

js
import { EventEmitter } from 'node:events'
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()

const callbackA = () => {
  console.log('A')
  myEmitter.removeListener('event', callbackB)
}

const callbackB = () => {
  console.log('B')
}

myEmitter.on('event', callbackA)

myEmitter.on('event', callbackB)

// callbackA 移除监听器 callbackB,但它仍将被调用。
// 发射时的内部监听器数组 [callbackA, callbackB]
myEmitter.emit('event')
// 打印:
//   A
//   B

// callbackB 现在已移除。
// 内部监听器数组 [callbackA]
myEmitter.emit('event')
// 打印:
//   A
js
const EventEmitter = require('node:events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()

const callbackA = () => {
  console.log('A')
  myEmitter.removeListener('event', callbackB)
}

const callbackB = () => {
  console.log('B')
}

myEmitter.on('event', callbackA)

myEmitter.on('event', callbackB)

// callbackA 移除监听器 callbackB,但它仍将被调用。
// 发射时的内部监听器数组 [callbackA, callbackB]
myEmitter.emit('event')
// 打印:
//   A
//   B

// callbackB 现在已移除。
// 内部监听器数组 [callbackA]
myEmitter.emit('event')
// 打印:
//   A

因为监听器是使用内部数组管理的,所以调用此方法将更改任何在被移除的监听器之后注册的监听器的索引位置。这不会影响监听器调用的顺序,但这意味着由 emitter.listeners() 方法返回的任何监听器数组的副本都需要重新创建。

当单个函数已被多次添加为单个事件的处理程序时(如下例所示),removeListener() 将移除最近添加的实例。在示例中,once('ping') 监听器被移除:

js
import { EventEmitter } from 'node:events'
const ee = new EventEmitter()

function pong() {
  console.log('pong')
}

ee.on('ping', pong)
ee.once('ping', pong)
ee.removeListener('ping', pong)

ee.emit('ping')
ee.emit('ping')
js
const EventEmitter = require('node:events')
const ee = new EventEmitter()

function pong() {
  console.log('pong')
}

ee.on('ping', pong)
ee.once('ping', pong)
ee.removeListener('ping', pong)

ee.emit('ping')
ee.emit('ping')

返回 EventEmitter 的引用,以便可以链接调用。

emitter.setMaxListeners(n)

新增于: v0.3.5

默认情况下,如果为特定事件添加了超过 10 个监听器,EventEmitter 将打印警告。这是一个有用的默认设置,有助于查找内存泄漏。emitter.setMaxListeners() 方法允许为此特定 EventEmitter 实例修改此限制。该值可以设置为 Infinity(或 0)以指示无限数量的监听器。

返回 EventEmitter 的引用,以便可以链接调用。

emitter.rawListeners(eventName)

新增于: v9.4.0

返回名为 eventName 的事件的监听器数组的副本,包括任何包装器(例如由 .once() 创建的包装器)。

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// 返回一个新数组,其中包含一个函数 `onceWrapper`,该函数具有一个属性
// `listener`,其中包含上面绑定的原始监听器
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// 将“log once”记录到控制台,并且不取消绑定 `once` 事件
logFnWrapper.listener()

// 将“log once”记录到控制台并删除监听器
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// 将返回一个新数组,其中包含上面由 `.on()` 绑定的单个函数
const newListeners = emitter.rawListeners('log')

// 将“log persistently”记录两次
newListeners[0]()
emitter.emit('log')
js
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.once('log', () => console.log('log once'))

// 返回一个新数组,其中包含一个函数 `onceWrapper`,该函数具有一个属性
// `listener`,其中包含上面绑定的原始监听器
const listeners = emitter.rawListeners('log')
const logFnWrapper = listeners[0]

// 将“log once”记录到控制台,并且不取消绑定 `once` 事件
logFnWrapper.listener()

// 将“log once”记录到控制台并删除监听器
logFnWrapper()

emitter.on('log', () => console.log('log persistently'))
// 将返回一个新数组,其中包含上面由 `.on()` 绑定的单个函数
const newListeners = emitter.rawListeners('log')

// 将“log persistently”记录两次
newListeners[0]()
emitter.emit('log')

emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])

[历史]

版本变更
v17.4.0, v16.14.0移除实验性标识。
v13.4.0, v12.16.0v13.4.0, v12.16.0 版本中添加

当事件发出时发生 Promise 拒绝,并且在发射器上启用了 captureRejections 时,将调用 Symbol.for('nodejs.rejection') 方法。可以使用 events.captureRejectionSymbol 来代替 Symbol.for('nodejs.rejection')

js
import { EventEmitter, captureRejectionSymbol } from 'node:events'

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('rejection happened for', event, 'with', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // 在此处销毁资源。
  }
}
js
const { EventEmitter, captureRejectionSymbol } = require('node:events')

class MyClass extends EventEmitter {
  constructor() {
    super({ captureRejections: true })
  }

  [captureRejectionSymbol](err, event, ...args) {
    console.log('rejection happened for', event, 'with', err, ...args)
    this.destroy(err)
  }

  destroy(err) {
    // 在此处销毁资源。
  }
}

events.defaultMaxListeners

新增于:v0.11.2

默认情况下,任何单个事件最多可以注册 10 个监听器。可以使用 emitter.setMaxListeners(n) 方法更改单个 EventEmitter 实例的此限制。要更改所有 EventEmitter 实例的默认值,可以使用 events.defaultMaxListeners 属性。如果此值不是正数,则会抛出 RangeError

更改 events.defaultMaxListeners 时要谨慎,因为此更改会影响 所有 EventEmitter 实例,包括在更改之前创建的实例。但是,调用 emitter.setMaxListeners(n) 仍然优先于 events.defaultMaxListeners

这不是硬性限制。EventEmitter 实例将允许添加更多监听器,但会向 stderr 输出跟踪警告,指示已检测到“可能的 EventEmitter 内存泄漏”。对于任何单个 EventEmitter,可以使用 emitter.getMaxListeners()emitter.setMaxListeners() 方法来临时避免此警告:

defaultMaxListenersAbortSignal 实例无效。虽然仍然可以使用 emitter.setMaxListeners(n) 为单个 AbortSignal 实例设置警告限制,但默认情况下 AbortSignal 实例不会发出警告。

js
import { EventEmitter } from 'node:events'
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})
js
const EventEmitter = require('node:events')
const emitter = new EventEmitter()
emitter.setMaxListeners(emitter.getMaxListeners() + 1)
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0))
})

可以使用 --trace-warnings 命令行标志显示此类警告的堆栈跟踪。

可以使用 process.on('warning') 检查发出的警告,并且它将具有附加的 emittertypecount 属性,分别指代事件发射器实例、事件名称和附加的监听器数量。其 name 属性设置为 'MaxListenersExceededWarning'

events.errorMonitor

新增于:v13.6.0, v12.17.0

此符号用于安装仅监听 'error' 事件的监听器。使用此符号安装的监听器会在常规 'error' 监听器调用之前调用。

使用此符号安装监听器不会改变发出 'error' 事件后的行为。因此,如果没有安装常规的 'error' 监听器,进程仍然会崩溃。

events.getEventListeners(emitterOrTarget, eventName)

新增于:v15.2.0, v14.17.0

返回名为 eventName 的事件的监听器数组的副本。

对于 EventEmitter,这与在发射器上调用 .listeners 的行为完全相同。

对于 EventTarget,这是获取事件目标的事件监听器的唯一方法。这对于调试和诊断目的非常有用。

js
import { getEventListeners, EventEmitter } from 'node:events'

{
  const ee = new EventEmitter()
  const listener = () => console.log('Events are fun')
  ee.on('foo', listener)
  console.log(getEventListeners(ee, 'foo')) // [ [Function: listener] ]
}
{
  const et = new EventTarget()
  const listener = () => console.log('Events are fun')
  et.addEventListener('foo', listener)
  console.log(getEventListeners(et, 'foo')) // [ [Function: listener] ]
}
js
const { getEventListeners, EventEmitter } = require('node:events')

{
  const ee = new EventEmitter()
  const listener = () => console.log('Events are fun')
  ee.on('foo', listener)
  console.log(getEventListeners(ee, 'foo')) // [ [Function: listener] ]
}
{
  const et = new EventTarget()
  const listener = () => console.log('Events are fun')
  et.addEventListener('foo', listener)
  console.log(getEventListeners(et, 'foo')) // [ [Function: listener] ]
}

events.getMaxListeners(emitterOrTarget)

新增于:v19.9.0, v18.17.0

返回当前设置的最大监听器数量。

对于 EventEmitter,这与在发射器上调用 .getMaxListeners 的行为完全相同。

对于 EventTarget,这是获取事件目标最大事件监听器的唯一方法。如果单个 EventTarget 上的事件处理程序数量超过设置的最大值,EventTarget 将打印警告。

js
import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events'

{
  const ee = new EventEmitter()
  console.log(getMaxListeners(ee)) // 10
  setMaxListeners(11, ee)
  console.log(getMaxListeners(ee)) // 11
}
{
  const et = new EventTarget()
  console.log(getMaxListeners(et)) // 10
  setMaxListeners(11, et)
  console.log(getMaxListeners(et)) // 11
}
js
const { getMaxListeners, setMaxListeners, EventEmitter } = require('node:events')

{
  const ee = new EventEmitter()
  console.log(getMaxListeners(ee)) // 10
  setMaxListeners(11, ee)
  console.log(getMaxListeners(ee)) // 11
}
{
  const et = new EventTarget()
  console.log(getMaxListeners(et)) // 10
  setMaxListeners(11, et)
  console.log(getMaxListeners(et)) // 11
}

events.once(emitter, name[, options])

[历史]

版本变更
v15.0.0现在支持 signal 选项。
v11.13.0, v10.16.0添加于:v11.13.0, v10.16.0

创建一个 Promise,当 EventEmitter 发出给定事件时,该 Promise 就会 fulfilled;如果 EventEmitter 在等待过程中发出 'error' 事件,则该 Promise 就会 rejected。该 Promise 将解析为一个数组,其中包含发出给定事件的所有参数。

此方法故意设计为通用的,并且可与 Web 平台 EventTarget 接口一起使用,该接口没有特殊的 'error' 事件语义,也不会监听 'error' 事件。

js
import { once, EventEmitter } from 'node:events'
import process from 'node:process'

const ee = new EventEmitter()

process.nextTick(() => {
  ee.emit('myevent', 42)
})

const [value] = await once(ee, 'myevent')
console.log(value)

const err = new Error('kaboom')
process.nextTick(() => {
  ee.emit('error', err)
})

try {
  await once(ee, 'myevent')
} catch (err) {
  console.error('error happened', err)
}
js
const { once, EventEmitter } = require('node:events')

async function run() {
  const ee = new EventEmitter()

  process.nextTick(() => {
    ee.emit('myevent', 42)
  })

  const [value] = await once(ee, 'myevent')
  console.log(value)

  const err = new Error('kaboom')
  process.nextTick(() => {
    ee.emit('error', err)
  })

  try {
    await once(ee, 'myevent')
  } catch (err) {
    console.error('error happened', err)
  }
}

run()

只有当 events.once() 用于等待另一个事件时,才会使用对 'error' 事件的特殊处理。如果 events.once() 用于等待 'error' 事件本身,则将其视为任何其他类型的事件,无需特殊处理:

js
import { EventEmitter, once } from 'node:events'

const ee = new EventEmitter()

once(ee, 'error')
  .then(([err]) => console.log('ok', err.message))
  .catch(err => console.error('error', err.message))

ee.emit('error', new Error('boom'))

// Prints: ok boom
js
const { EventEmitter, once } = require('node:events')

const ee = new EventEmitter()

once(ee, 'error')
  .then(([err]) => console.log('ok', err.message))
  .catch(err => console.error('error', err.message))

ee.emit('error', new Error('boom'))

// Prints: ok boom

可以使用 <AbortSignal> 取消等待事件:

js
import { EventEmitter, once } from 'node:events'

const ee = new EventEmitter()
const ac = new AbortController()

async function foo(emitter, event, signal) {
  try {
    await once(emitter, event, { signal })
    console.log('event emitted!')
  } catch (error) {
    if (error.name === 'AbortError') {
      console.error('Waiting for the event was canceled!')
    } else {
      console.error('There was an error', error.message)
    }
  }
}

foo(ee, 'foo', ac.signal)
ac.abort() // Prints: Waiting for the event was canceled!
js
const { EventEmitter, once } = require('node:events')

const ee = new EventEmitter()
const ac = new AbortController()

async function foo(emitter, event, signal) {
  try {
    await once(emitter, event, { signal })
    console.log('event emitted!')
  } catch (error) {
    if (error.name === 'AbortError') {
      console.error('Waiting for the event was canceled!')
    } else {
      console.error('There was an error', error.message)
    }
  }
}

foo(ee, 'foo', ac.signal)
ac.abort() // Prints: Waiting for the event was canceled!

等待 process.nextTick() 上发出的多个事件

使用 events.once() 函数等待在同一批 process.nextTick() 操作中发出的多个事件,或者在同步发出多个事件时,存在一个值得注意的边缘情况。具体来说,因为 process.nextTick() 队列在 Promise 微任务队列之前被清空,并且因为 EventEmitter 同步发出所有事件,所以 events.once() 可能错过一个事件。

js
import { EventEmitter, once } from 'node:events'
import process from 'node:process'

const myEE = new EventEmitter()

async function foo() {
  await once(myEE, 'bar')
  console.log('bar')

  // 此 Promise 将永远不会被解决,因为 'foo' 事件将在创建 Promise 之前就已经发出。
  await once(myEE, 'foo')
  console.log('foo')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))
js
const { EventEmitter, once } = require('node:events')

const myEE = new EventEmitter()

async function foo() {
  await once(myEE, 'bar')
  console.log('bar')

  // 此 Promise 将永远不会被解决,因为 'foo' 事件将在创建 Promise 之前就已经发出。
  await once(myEE, 'foo')
  console.log('foo')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))

为了捕获这两个事件,在等待任何一个事件之前创建每个 Promise,然后就可以使用 Promise.all()Promise.race()Promise.allSettled()

js
import { EventEmitter, once } from 'node:events'
import process from 'node:process'

const myEE = new EventEmitter()

async function foo() {
  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')])
  console.log('foo', 'bar')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))
js
const { EventEmitter, once } = require('node:events')

const myEE = new EventEmitter()

async function foo() {
  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')])
  console.log('foo', 'bar')
}

process.nextTick(() => {
  myEE.emit('bar')
  myEE.emit('foo')
})

foo().then(() => console.log('done'))

events.captureRejections

[历史]

版本变更
v17.4.0, v16.14.0移除实验性标识。
v13.4.0, v12.16.0v13.4.0, v12.16.0 版本中添加

值: <布尔值>

更改所有新的 EventEmitter 对象上的默认 captureRejections 选项。

events.captureRejectionSymbol

[历史]

版本变更
v17.4.0, v16.14.0移除实验性标识。
v13.4.0, v12.16.0v13.4.0, v12.16.0 版本中添加

值: Symbol.for('nodejs.rejection')

查看如何编写自定义的 拒绝处理程序

events.listenerCount(emitter, eventName)

添加于: v0.9.12

自 v3.2.0 起弃用

[稳定性: 0 - 已弃用]

稳定性: 0 稳定性: 0 - 已弃用: 请使用 emitter.listenerCount() 代替。

一个类方法,返回给定 emitter 上为给定 eventName 注册的监听器数量。

js
import { EventEmitter, listenerCount } from 'node:events'

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// 输出: 2
js
const { EventEmitter, listenerCount } = require('node:events')

const myEmitter = new EventEmitter()
myEmitter.on('event', () => {})
myEmitter.on('event', () => {})
console.log(listenerCount(myEmitter, 'event'))
// 输出: 2

events.on(emitter, eventName[, options])

[历史]

版本变更
v22.0.0, v20.13.0支持 highWaterMarklowWaterMark 选项,为保持一致性。旧选项仍然支持。
v20.0.0现在支持 closehighWatermarklowWatermark 选项。
v13.6.0, v12.16.0新增于:v13.6.0, v12.16.0
  • emitter <EventEmitter>

  • eventName <string> | <symbol> 正在监听的事件名称

  • options <Object>

    • signal <AbortSignal> 可用于取消等待事件。
    • close - <string[]> 将结束迭代的事件名称。
    • highWaterMark - <integer> 默认值: Number.MAX_SAFE_INTEGER 高水位线。每当缓冲的事件大小高于此值时,发射器就会暂停。仅支持实现 pause()resume() 方法的发射器。
    • lowWaterMark - <integer> 默认值: 1 低水位线。每当缓冲的事件大小低于此值时,发射器就会恢复。仅支持实现 pause()resume() 方法的发射器。
  • 返回: <AsyncIterator> 迭代 emitter 发出的 eventName 事件

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ee = new EventEmitter()

// 稍后发出
process.nextTick(() => {
  ee.emit('foo', 'bar')
  ee.emit('foo', 42)
})

for await (const event of on(ee, 'foo')) {
  // 此内部块的执行是同步的,它一次处理一个事件(即使使用 await)。如果需要并发执行,请勿使用。
  console.log(event) // 打印 ['bar'] [42]
}
// 此处不可达
js
const { on, EventEmitter } = require('node:events')

;(async () => {
  const ee = new EventEmitter()

  // 稍后发出
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo')) {
    // 此内部块的执行是同步的,它一次处理一个事件(即使使用 await)。如果需要并发执行,请勿使用。
    console.log(event) // 打印 ['bar'] [42]
  }
  // 此处不可达
})()

返回一个 AsyncIterator,它迭代 eventName 事件。如果 EventEmitter 发出 'error',它将抛出错误。它在退出循环时会移除所有监听器。每次迭代返回的 value 是一个数组,由发出的事件参数组成。

可以使用 <AbortSignal> 取消等待事件:

js
import { on, EventEmitter } from 'node:events'
import process from 'node:process'

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // 稍后发出
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // 此内部块的执行是同步的,它一次处理一个事件(即使使用 await)。如果需要并发执行,请勿使用。
    console.log(event) // 打印 ['bar'] [42]
  }
  // 此处不可达
})()

process.nextTick(() => ac.abort())
js
const { on, EventEmitter } = require('node:events')

const ac = new AbortController()

;(async () => {
  const ee = new EventEmitter()

  // 稍后发出
  process.nextTick(() => {
    ee.emit('foo', 'bar')
    ee.emit('foo', 42)
  })

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // 此内部块的执行是同步的,它一次处理一个事件(即使使用 await)。如果需要并发执行,请勿使用。
    console.log(event) // 打印 ['bar'] [42]
  }
  // 此处不可达
})()

process.nextTick(() => ac.abort())

events.setMaxListeners(n[, ...eventTargets])

新增于:v15.4.0

js
import { setMaxListeners, EventEmitter } from 'node:events'

const target = new EventTarget()
const emitter = new EventEmitter()

setMaxListeners(5, target, emitter)
js
const { setMaxListeners, EventEmitter } = require('node:events')

const target = new EventTarget()
const emitter = new EventEmitter()

setMaxListeners(5, target, emitter)

events.addAbortListener(signal, listener)

新增于: v20.5.0, v18.18.0

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

监听提供的 signal 上的 abort 事件一次。

监听中止信号上的 abort 事件是不安全的,并且可能导致资源泄漏,因为另一个拥有该信号的第三方可以调用 e.stopImmediatePropagation()。不幸的是,Node.js 无法更改这一点,因为这会违反 Web 标准。此外,原始 API 使人们很容易忘记移除监听器。

此 API 通过解决这两个问题来允许在 Node.js API 中安全地使用 AbortSignal,方法是监听事件,以便 stopImmediatePropagation 不会阻止监听器运行。

返回一个 disposable 对象,以便更容易取消订阅。

js
const { addAbortListener } = require('node:events')

function example(signal) {
  let disposable
  try {
    signal.addEventListener('abort', e => e.stopImmediatePropagation())
    disposable = addAbortListener(signal, e => {
      // 当信号中止时执行某些操作。
    })
  } finally {
    disposable?.[Symbol.dispose]()
  }
}
js
import { addAbortListener } from 'node:events'

function example(signal) {
  let disposable
  try {
    signal.addEventListener('abort', e => e.stopImmediatePropagation())
    disposable = addAbortListener(signal, e => {
      // 当信号中止时执行某些操作。
    })
  } finally {
    disposable?.[Symbol.dispose]()
  }
}

类: events.EventEmitterAsyncResource extends EventEmitter

新增于: v17.4.0, v16.14.0

EventEmitter<AsyncResource> 集成,用于需要手动异步跟踪的 EventEmitter。具体来说,events.EventEmitterAsyncResource 实例发出的所有事件都将在其 异步上下文 中运行。

js
import { EventEmitterAsyncResource, EventEmitter } from 'node:events'
import { notStrictEqual, strictEqual } from 'node:assert'
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks'

// 异步跟踪工具会将其识别为“Q”。
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// 'foo' 监听器将在 EventEmitter 的异步上下文中运行。
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// 然而,在不跟踪异步上下文的普通 EventEmitter 上的 'foo' 监听器,将在与 emit() 相同的异步上下文中运行。
ee2.on('foo', () => {
  notStrictEqual(executionAsyncId(), ee2.asyncId)
  notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})

Promise.resolve().then(() => {
  ee1.emit('foo')
  ee2.emit('foo')
})
js
const { EventEmitterAsyncResource, EventEmitter } = require('node:events')
const { notStrictEqual, strictEqual } = require('node:assert')
const { executionAsyncId, triggerAsyncId } = require('node:async_hooks')

// 异步跟踪工具会将其识别为“Q”。
const ee1 = new EventEmitterAsyncResource({ name: 'Q' })

// 'foo' 监听器将在 EventEmitter 的异步上下文中运行。
ee1.on('foo', () => {
  strictEqual(executionAsyncId(), ee1.asyncId)
  strictEqual(triggerAsyncId(), ee1.triggerAsyncId)
})

const ee2 = new EventEmitter()

// 然而,在不跟踪异步上下文的普通 EventEmitter 上的 'foo' 监听器,将在与 emit() 相同的异步上下文中运行。
ee2.on('foo', () => {
  notStrictEqual(executionAsyncId(), ee2.asyncId)
  notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId)
})

Promise.resolve().then(() => {
  ee1.emit('foo')
  ee2.emit('foo')
})

EventEmitterAsyncResource 类具有与 EventEmitterAsyncResource 本身相同的方法,并接受相同的选项。

new events.EventEmitterAsyncResource([options])

  • options <对象>
    • captureRejections <布尔值> 启用自动捕获 Promise 拒绝默认值:false
    • name <字符串> 异步事件的类型。默认值:new.target.name
    • triggerAsyncId <数字> 创建此异步事件的执行上下文的 ID。默认值:executionAsyncId()
    • requireManualDestroy <布尔值> 如果设置为 true,则在对象被垃圾回收时禁用 emitDestroy。通常不需要设置此选项(即使手动调用 emitDestroy),除非检索资源的 asyncId 并使用它调用敏感 API 的 emitDestroy。如果设置为 false,则只有当至少有一个活动的 destroy 钩子时,垃圾回收才会调用 emitDestroy默认值:false

eventemitterasyncresource.asyncId

  • 类型: <数字> 分配给资源的唯一 asyncId

eventemitterasyncresource.asyncResource

返回的 AsyncResource 对象具有一个附加的 eventEmitter 属性,该属性提供对该 EventEmitterAsyncResource 的引用。

eventemitterasyncresource.emitDestroy()

调用所有 destroy 钩子。这只能调用一次。如果调用多次,则会抛出错误。这必须手动调用。如果资源被 GC 收集,则 destroy 钩子将永远不会被调用。

eventemitterasyncresource.triggerAsyncId

  • 类型: <数字> 传递给 AsyncResource 构造函数的相同 triggerAsyncId

EventTargetEvent API

[历史]

版本变更
v16.0.0更改了 EventTarget 错误处理。
v15.4.0不再是实验性功能。
v15.0.0EventTargetEvent 类现在可用作全局变量。
v14.5.0添加于:v14.5.0

EventTargetEvent 对象是 Node.js 特定的 EventTarget Web API 实现,由一些 Node.js 核心 API 公开。

js
const target = new EventTarget()

target.addEventListener('foo', event => {
  console.log('foo 事件发生了!')
})

Node.js EventTarget 与 DOM EventTarget

Node.js 的 EventTargetEventTarget Web API 之间存在两个主要区别:

NodeEventTargetEventEmitter

NodeEventTarget 对象实现了 EventEmitter API 的一个修改后的子集,使其能够在某些情况下模拟 EventEmitterNodeEventTarget 不是 EventEmitter 的实例,在大多数情况下不能替代 EventEmitter

事件监听器

为事件 type 注册的事件监听器可以是 JavaScript 函数,也可以是具有 handleEvent 属性的对象,该属性的值是一个函数。

在这两种情况下,处理程序函数都会使用传递给 eventTarget.dispatchEvent() 函数的 event 参数调用。

异步函数可以用作事件监听器。如果异步处理程序函数被拒绝,则会捕获并处理该拒绝,如EventTarget 错误处理中所述。

一个处理程序函数抛出的错误不会阻止其他处理程序被调用。

处理程序函数的返回值将被忽略。

处理程序始终按照添加它们的顺序调用。

处理程序函数可以修改 event 对象。

js
function handler1(event) {
  console.log(event.type) // 打印 'foo'
  event.a = 1
}

async function handler2(event) {
  console.log(event.type) // 打印 'foo'
  console.log(event.a) // 打印 1
}

const handler3 = {
  handleEvent(event) {
    console.log(event.type) // 打印 'foo'
  },
}

const handler4 = {
  async handleEvent(event) {
    console.log(event.type) // 打印 'foo'
  },
}

const target = new EventTarget()

target.addEventListener('foo', handler1)
target.addEventListener('foo', handler2)
target.addEventListener('foo', handler3)
target.addEventListener('foo', handler4, { once: true })

EventTarget 错误处理

当注册的事件监听器抛出错误(或返回一个被拒绝的 Promise)时,默认情况下,该错误会被视为 process.nextTick() 上的未捕获异常。这意味着 EventTarget 中的未捕获异常默认情况下会终止 Node.js 进程。

在事件监听器中抛出错误 不会 阻止其他已注册的处理程序被调用。

EventTarget 不像 EventEmitter 一样实现任何针对 'error' 类型事件的特殊默认处理。

目前,错误会在到达 process.on('uncaughtException') 之前首先转发到 process.on('error') 事件。此行为已弃用,并在未来版本中将更改为使 EventTarget 与其他 Node.js API 保持一致。任何依赖 process.on('error') 事件的代码都应与新行为保持一致。

类: Event

[历史]

版本变更
v15.0.0Event 类现在可通过全局对象访问。
v14.5.0新增于:v14.5.0

Event 对象是 Event Web API 的一个适配器。实例由 Node.js 内部创建。

event.bubbles

新增于: v14.5.0

此属性在 Node.js 中未使用,仅为完整性而提供。

event.cancelBubble

新增于: v14.5.0

[稳定性: 3 - 已弃用]

稳定性: 3 稳定性: 3 - 已弃用: 请改用 event.stopPropagation()

如果设置为 true,则为 event.stopPropagation() 的别名。此属性在 Node.js 中未使用,仅为完整性而提供。

event.cancelable

新增于: v14.5.0

  • 类型: <boolean> 如果事件是用 cancelable 选项创建的,则为 true

event.composed

新增于: v14.5.0

此属性在 Node.js 中未使用,仅为完整性而提供。

event.composedPath()

新增于:v14.5.0

返回一个数组,其中包含当前的 EventTarget 作为唯一条目,如果事件未被分发则返回空数组。这在 Node.js 中未使用,仅为完整性而提供。

event.currentTarget

新增于:v14.5.0

event.target 的别名。

event.defaultPrevented

新增于:v14.5.0

如果 cancelabletrue 并且调用了 event.preventDefault(),则为 true

event.eventPhase

新增于:v14.5.0

  • 类型:<number> 当事件未被分发时返回 0,当事件正在被分发时返回 2

这在 Node.js 中未使用,仅为完整性而提供。

event.initEvent(type[, bubbles[, cancelable]])

新增于:v19.5.0

[稳定性:3 - 已弃用]

稳定性:3 稳定性:3 - 已弃用:WHATWG 规范认为它已弃用,用户根本不应该使用它。

与事件构造函数冗余,并且无法设置 composed。这在 Node.js 中未使用,仅为完整性而提供。

event.isTrusted

新增于:v14.5.0

<AbortSignal> "abort" 事件发出时,isTrusted 设置为 true。在所有其他情况下,其值为 false

event.preventDefault()

新增于:v14.5.0

如果 cancelabletrue,则将 defaultPrevented 属性设置为 true

event.returnValue

新增于:v14.5.0

[稳定:3 - 遗留]

稳定:3 稳定性:3 - 遗留:请改用 event.defaultPrevented

  • 类型:<boolean> 如果事件未被取消,则为 true

event.returnValue 的值始终与 event.defaultPrevented 相反。这在 Node.js 中未使用,仅出于完整性考虑而提供。

event.srcElement

新增于:v14.5.0

[稳定性:3 - 已弃用]

稳定性:3 稳定性:3 - 已弃用:请改用 event.target

event.target 的别名。

event.stopImmediatePropagation()

新增于:v14.5.0

停止在当前事件监听器完成之后调用其他事件监听器。

event.stopPropagation()

新增于:v14.5.0

此方法在 Node.js 中未使用,仅为完整性而提供。

event.target

新增于:v14.5.0

event.timeStamp

新增于:v14.5.0

创建 Event 对象时的毫秒时间戳。

event.type

新增于:v14.5.0

事件类型标识符。

类: EventTarget

[历史]

版本变更
v15.0.0EventTarget 类现在可通过全局对象访问。
v14.5.0在 v14.5.0 中添加

eventTarget.addEventListener(type, listener[, options])

[历史]

版本变更
v15.4.0添加对 signal 选项的支持。
v14.5.0在 v14.5.0 中添加
  • type <字符串>
  • listener <函数> | <事件监听器>
  • options <对象>
    • once <布尔值> 当值为 true 时,监听器在第一次被调用时会自动移除。默认值: false
    • passive <布尔值> 当值为 true 时,提示监听器不会调用 Event 对象的 preventDefault() 方法。默认值: false
    • capture <布尔值> Node.js 不直接使用。出于 API 完整性而添加。默认值: false
    • signal <AbortSignal> 当给定的 AbortSignal 对象的 abort() 方法被调用时,监听器将被移除。

添加一个针对 type 事件的新处理程序。任何给定的 listener 对于每个 type 和每个 capture 选项值只添加一次。

如果 once 选项为 true,则在下次分派 type 事件后,listener 将被移除。

capture 选项在 Node.js 中除了根据 EventTarget 规范跟踪已注册的事件监听器之外,没有任何功能上的用途。具体来说,capture 选项在注册 listener 时用作键的一部分。任何单个 listener 可以使用 capture = false 添加一次,也可以使用 capture = true 添加一次。

js
function handler(event) {}

const target = new EventTarget()
target.addEventListener('foo', handler, { capture: true }) // 第一个
target.addEventListener('foo', handler, { capture: false }) // 第二个

// 移除第二个 handler 实例
target.removeEventListener('foo', handler)

// 移除第一个 handler 实例
target.removeEventListener('foo', handler, { capture: true })

eventTarget.dispatchEvent(event)

新增于: v14.5.0

  • event <Event>
  • 返回值: <boolean> 如果事件的 cancelable 属性值为 false 或其 preventDefault() 方法未被调用,则返回 true,否则返回 false

event 分派到 event.type 的处理程序列表。

已注册的事件监听器将按照注册顺序同步调用。

eventTarget.removeEventListener(type, listener[, options])

新增于: v14.5.0

从事件 type 的处理程序列表中移除 listener

类: CustomEvent

[历史]

版本变更
v23.0.0不再是实验性功能。
v22.1.0, v20.13.0CustomEvent 现在稳定。
v19.0.0不再需要 --experimental-global-customevent CLI 标记。
v18.7.0, v16.17.0新增于:v18.7.0, v16.17.0

[稳定性: 2 - 稳定]

稳定性: 2 稳定性: 2 - 稳定

CustomEvent 对象是对 CustomEvent Web API 的改编。实例由 Node.js 内部创建。

event.detail

[历史]

版本变更
v22.1.0, v20.13.0CustomEvent 现在稳定。
v18.7.0, v16.17.0新增于:v18.7.0, v16.17.0

[稳定性: 2 - 稳定]

稳定性: 2 稳定性: 2 - 稳定

  • 类型: <any> 返回初始化时传递的自定义数据。

只读。

类: NodeEventTarget

新增于: v14.5.0

NodeEventTargetEventTarget 的 Node.js 特定扩展,它模拟了 EventEmitter API 的一个子集。

nodeEventTarget.addListener(type, listener)

新增于: v14.5.0

Node.js 对 EventTarget 类的特定扩展,模拟了等效的 EventEmitter API。addListener()addEventListener() 之间的唯一区别在于 addListener() 将返回对 EventTarget 的引用。

nodeEventTarget.emit(type, arg)

新增于: v15.2.0

  • type <string>
  • arg <any>
  • 返回: <boolean> 如果为 type 注册了事件监听器,则返回 true,否则返回 false

Node.js 对 EventTarget 类的特定扩展,它将 arg 分派给 type 的处理程序列表。

nodeEventTarget.eventNames()

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展,返回已注册事件监听器的事件 type 名称数组。

nodeEventTarget.listenerCount(type)

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展,返回为 type 注册的事件监听器数量。

nodeEventTarget.setMaxListeners(n)

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展,将最大事件监听器数量设置为 n

nodeEventTarget.getMaxListeners()

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展,返回最大事件监听器数量。

nodeEventTarget.off(type, listener[, options])

新增于:v14.5.0

Node.js 对 eventTarget.removeEventListener() 的特定别名。

nodeEventTarget.on(type, listener)

新增于: v14.5.0

eventTarget.addEventListener() 的 Node.js 专用别名。

nodeEventTarget.once(type, listener)

新增于: v14.5.0

EventTarget 类的 Node.js 专用扩展,为给定的事件 type 添加一个 once 监听器。这等效于将 once 选项设置为 true 并调用 on

nodeEventTarget.removeAllListeners([type])

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展。如果指定了 type,则删除为 type 注册的所有监听器,否则删除所有注册的监听器。

nodeEventTarget.removeListener(type, listener[, options])

新增于:v14.5.0

Node.js 对 EventTarget 类的特定扩展,用于删除给定 typelistenerremoveListener()removeEventListener() 之间的唯一区别在于 removeListener() 将返回对 EventTarget 的引用。