Node.js v25.0.0 文档
- Node.js v25.0.0
-
目录
- 事件
- 向监听器传递参数和
this - 异步 vs. 同步
- 仅处理一次事件
- 错误事件
- 捕获 promise 的拒绝
- 类:
EventEmitter- 事件:
'newListener' - 事件:
'removeListener' emitter.addListener(eventName, listener)emitter.emit(eventName[, ...args])emitter.eventNames()emitter.getMaxListeners()emitter.listenerCount(eventName[, listener])emitter.listeners(eventName)emitter.off(eventName, listener)emitter.on(eventName, listener)emitter.once(eventName, listener)emitter.prependListener(eventName, listener)emitter.prependOnceListener(eventName, listener)emitter.removeAllListeners([eventName])emitter.removeListener(eventName, listener)emitter.setMaxListeners(n)emitter.rawListeners(eventName)emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])
- 事件:
events.defaultMaxListenersevents.errorMonitorevents.getEventListeners(emitterOrTarget, eventName)events.getMaxListeners(emitterOrTarget)events.once(emitter, name[, options])events.captureRejectionsevents.captureRejectionSymbolevents.listenerCount(emitter, eventName)events.on(emitter, eventName[, options])events.setMaxListeners(n[, ...eventTargets])events.addAbortListener(signal, listener)- 类:
events.EventEmitterAsyncResource extends EventEmitter EventTarget和EventAPI- Node.js
EventTarget与 DOMEventTarget的对比 NodeEventTarget与EventEmitter的对比- 事件监听器
EventTarget错误处理- 类:
Eventevent.bubblesevent.cancelBubbleevent.cancelableevent.composedevent.composedPath()event.currentTargetevent.defaultPreventedevent.eventPhaseevent.initEvent(type[, bubbles[, cancelable]])event.isTrustedevent.preventDefault()event.returnValueevent.srcElementevent.stopImmediatePropagation()event.stopPropagation()event.targetevent.timeStampevent.type
- 类:
EventTarget - 类:
CustomEvent - 类:
NodeEventTargetnodeEventTarget.addListener(type, listener)nodeEventTarget.emit(type, arg)nodeEventTarget.eventNames()nodeEventTarget.listenerCount(type)nodeEventTarget.setMaxListeners(n)nodeEventTarget.getMaxListeners()nodeEventTarget.off(type, listener[, options])nodeEventTarget.on(type, listener)nodeEventTarget.once(type, listener)nodeEventTarget.removeAllListeners([type])nodeEventTarget.removeListener(type, listener[, options])
- Node.js
- 向监听器传递参数和
- 事件
-
索引
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 环境变量
- 错误
- 事件
- 文件系统
- 全局对象
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:moduleAPI - 模块:包
- 模块:TypeScript
- 网络
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 逐行读取
- REPL
- 报告
- 单一可执行文件应用
- SQLite
- 流
- 字符串解码器
- 测试运行器
- 定时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用工具
- V8
- 虚拟机
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- 其他版本
- 选项
事件#
源代码: lib/events.js
Node.js 核心 API 的大部分是围绕一种惯用的异步事件驱动架构构建的,其中某些类型的对象(称为“发射器”)会发出命名事件,从而导致 Function 对象(“监听器”)被调用。
例如:一个 net.Server 对象在每次有对等方连接时发出一个事件;一个 fs.ReadStream 在文件打开时发出一个事件;一个 流 在有数据可读时发出一个事件。
所有发出事件的对象都是 EventEmitter 类的实例。这些对象公开了一个 eventEmitter.on() 函数,允许将一个或多个函数附加到对象发出的命名事件上。通常,事件名称是驼峰式命名的字符串,但也可以使用任何有效的 JavaScript 属性键。
当 EventEmitter 对象发出一个事件时,所有附加到该特定事件的函数都会被同步调用。被调用的监听器返回的任何值都将被忽略并丢弃。
下面的示例展示了一个带有单个监听器的简单 EventEmitter 实例。eventEmitter.on() 方法用于注册监听器,而 eventEmitter.emit() 方法用于触发事件。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');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 实例。
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);
// Prints:
// 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');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);
// Prints:
// 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 实例。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b undefined
});
myEmitter.emit('event', 'a', 'b');const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
console.log(a, b, this);
// Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');
异步 vs. 同步#
EventEmitter 会按照监听器注册的顺序同步调用所有监听器。这确保了事件的正确排序,并有助于避免竞态条件和逻辑错误。在适当的时候,监听器函数可以使用 setImmediate() 或 process.nextTick() 方法切换到异步操作模式。
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');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() 方法注册一个监听器时,该监听器在每次发出命名事件时都会被调用。
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');
// Prints: 1
myEmitter.emit('event');
// Prints: 2const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
使用 eventEmitter.once() 方法,可以注册一个对于特定事件最多只调用一次的监听器。一旦事件被发出,监听器就会被注销,然后被调用。
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');
// Prints: 1
myEmitter.emit('event');
// Ignoredconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Ignored
错误事件#
当在 EventEmitter 实例中发生错误时,通常的操作是发出一个 'error' 事件。在 Node.js 中,这些被视为特殊情况。
如果一个 EventEmitter 没有为 'error' 事件注册至少一个监听器,并且发出了一个 'error' 事件,错误就会被抛出,打印堆栈跟踪,然后 Node.js 进程退出。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Throws and crashes Node.jsconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Throws and crashes Node.js
为防止 Node.js 进程崩溃,可以使用 domain 模块。(但请注意,node:domain 模块已被弃用。)
作为最佳实践,应始终为 'error' 事件添加监听器。
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!'));
// Prints: whoops! there was an errorconst 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!'));
// Prints: whoops! there was an error
可以通过使用符号 events.errorMonitor 安装监听器来监视 'error' 事件,而无需消费发出的错误。
import { EventEmitter, errorMonitor } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Still throws and crashes Node.jsconst { EventEmitter, errorMonitor } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Still throws and crashes Node.js
捕获 promise 的拒绝#
在事件处理程序中使用 async 函数是有问题的,因为在抛出异常的情况下可能导致未处理的拒绝。
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
ee.on('something', async (value) => {
throw new Error('kaboom');
});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' 事件处理程序。
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;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 实例的默认行为。
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);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' 事件没有捕获处理程序,以避免无限的错误循环:建议是不要使用 async 函数作为 'error' 事件处理程序。
类:EventEmitter#
EventEmitter 类由 node:events 模块定义和公开。
import { EventEmitter } from 'node:events';const EventEmitter = require('node:events');
所有 EventEmitter 在添加新监听器时会发出 'newListener' 事件,在移除现有监听器时会发出 'removeListener' 事件。
它支持以下选项:
captureRejections<boolean> 它启用自动捕获 promise 拒绝。默认值:false。
事件:'newListener'#
eventName<string> | <symbol> 正在监听的事件的名称listener<Function> 事件处理函数
EventEmitter 实例会在一个监听器被添加到其内部监听器数组之前发出自己的 'newListener' 事件。
为 'newListener' 事件注册的监听器会接收到事件名称和对正在添加的监听器的引用。
在添加监听器之前触发事件这一事实有一个微妙但重要的副作用:在 'newListener' 回调内部注册到同一 name 的任何额外监听器都会被插入到正在添加的监听器之前。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insert a new listener in front
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insert a new listener in front
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// A
事件:'removeListener'#
eventName<string> | <symbol> 事件名称listener<Function> 事件处理函数
'removeListener' 事件在 listener 被移除之后发出。
emitter.addListener(eventName, listener)#
eventName<string> | <symbol>listener<Function>
emitter.on(eventName, listener) 的别名。
emitter.emit(eventName[, ...args])#
按注册顺序同步调用为名为 eventName 的事件注册的每个监听器,并将提供的参数传递给每个监听器。
如果事件有监听器则返回 true,否则返回 false。
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();
// First listener
myEmitter.on('event', function firstListener() {
console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third 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);
// Prints:
// [
// [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 listenerconst EventEmitter = require('node:events');
const myEmitter = new EventEmitter();
// First listener
myEmitter.on('event', function firstListener() {
console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third 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);
// Prints:
// [
// [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()#
- 返回:<string[]> | <symbol[]>
返回一个数组,列出发射器已为其注册监听器的事件。
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());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]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());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]
emitter.getMaxListeners()#
- 返回:<integer>
返回 EventEmitter 的当前最大监听器值,该值要么由 emitter.setMaxListeners(n) 设置,要么默认为 events.defaultMaxListeners。
emitter.listenerCount(eventName[, listener])#
eventName<string> | <symbol> 正在监听的事件的名称listener<Function> 事件处理函数- 返回:<integer>
返回正在监听名为 eventName 的事件的监听器数量。如果提供了 listener,它将返回在事件的监听器列表中找到该监听器的次数。
emitter.listeners(eventName)#
eventName<string> | <symbol>- 返回:<Function[]>
返回名为 eventName 的事件的监听器数组的副本。
server.on('connection', (stream) => {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]
emitter.off(eventName, listener)#
eventName<string> | <symbol>listener<Function>- 返回:<EventEmitter>
emitter.on(eventName, listener)#
eventName<string> | <symbol> 事件的名称。listener<Function> 回调函数- 返回:<EventEmitter>
将 listener 函数添加到名为 eventName 的事件的监听器数组的末尾。不检查 listener 是否已被添加。多次传递相同的 eventName 和 listener 组合将导致 listener 被多次添加和调用。
server.on('connection', (stream) => {
console.log('someone connected!');
});
返回对 EventEmitter 的引用,以便可以链式调用。
默认情况下,事件监听器按添加顺序调用。emitter.prependListener() 方法可作为替代方案,将事件监听器添加到监听器数组的开头。
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// aconst EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.once(eventName, listener)#
eventName<string> | <symbol> 事件的名称。listener<Function> 回调函数- 返回:<EventEmitter>
为名为 eventName 的事件添加一个一次性的 listener 函数。下次触发 eventName 事件时,此监听器将被移除然后被调用。
server.once('connection', (stream) => {
console.log('Ah, we have our first user!');
});
返回对 EventEmitter 的引用,以便可以链式调用。
默认情况下,事件监听器按添加顺序调用。emitter.prependOnceListener() 方法可作为替代方案,将事件监听器添加到监听器数组的开头。
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// aconst EventEmitter = require('node:events');
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
emitter.prependListener(eventName, listener)#
eventName<string> | <symbol> 事件的名称。listener<Function> 回调函数- 返回:<EventEmitter>
将 listener 函数添加到名为 eventName 的事件的监听器数组的开头。不检查 listener 是否已被添加。多次传递相同的 eventName 和 listener 组合将导致 listener 被多次添加和调用。
server.prependListener('connection', (stream) => {
console.log('someone connected!');
});
返回对 EventEmitter 的引用,以便可以链式调用。
emitter.prependOnceListener(eventName, listener)#
eventName<string> | <symbol> 事件的名称。listener<Function> 回调函数- 返回:<EventEmitter>
为名为 eventName 的事件添加一个一次性的 listener 函数到监听器数组的开头。下次触发 eventName 事件时,此监听器将被移除,然后被调用。
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});
返回对 EventEmitter 的引用,以便可以链式调用。
emitter.removeAllListeners([eventName])#
eventName<string> | <symbol>- 返回:<EventEmitter>
移除所有监听器,或指定 eventName 的监听器。
移除在代码其他地方添加的监听器是一种不好的做法,特别是当 EventEmitter 实例是由其他组件或模块(例如套接字或文件流)创建时。
返回对 EventEmitter 的引用,以便可以链式调用。
emitter.removeListener(eventName, listener)#
eventName<string> | <symbol>listener<Function>- 返回:<EventEmitter>
从名为 eventName 的事件的监听器数组中移除指定的 listener。
const callback = (stream) => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
removeListener() 最多会从监听器数组中移除一个监听器实例。如果某个监听器已多次添加到指定 eventName 的监听器数组中,则必须多次调用 removeListener() 来移除每个实例。
一旦事件被发出,所有在发出时附加到它的监听器都会按顺序被调用。这意味着任何在发出之后、最后一个监听器执行完成之前的 removeListener() 或 removeAllListeners() 调用都不会将它们从进行中的 emit() 中移除。后续事件会按预期运行。
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 removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B
// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// Aconst 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 removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B
// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// A
因为监听器是使用内部数组管理的,所以调用此方法会改变在被移除的监听器之后注册的任何监听器的位置索引。这不会影响监听器的调用顺序,但这意味着通过 emitter.listeners() 方法返回的监听器数组的任何副本都需要重新创建。
当单个函数被多次添加为单个事件的处理程序时(如下例所示),removeListener() 将移除最近添加的实例。在示例中,once('ping') 监听器被移除了。
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');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)#
n<integer>- 返回:<EventEmitter>
默认情况下,如果为特定事件添加了超过 10 个监听器,EventEmitter 会打印一个警告。这是一个有用的默认设置,有助于发现内存泄漏。emitter.setMaxListeners() 方法允许为这个特定的 EventEmitter 实例修改此限制。该值可以设置为 Infinity(或 0)以表示无限数量的监听器。
返回对 EventEmitter 的引用,以便可以链式调用。
emitter.rawListeners(eventName)#
eventName<string> | <symbol>- 返回:<Function[]>
返回名为 eventName 的事件的监听器数组的副本,包括任何包装器(例如由 .once() 创建的包装器)。
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');
emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])#
如果在发出事件时发生 promise 拒绝,并且在发射器上启用了 captureRejections,则会调用 Symbol.for('nodejs.rejection') 方法。可以使用 events.captureRejectionSymbol 代替 Symbol.for('nodejs.rejection')。
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) {
// Tear the resource down here.
}
}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) {
// Tear the resource down here.
}
}
events.defaultMaxListeners#
默认情况下,任何单个事件最多可以注册 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() 方法临时避免此警告。
defaultMaxListeners 对 AbortSignal 实例没有影响。虽然仍然可以使用 emitter.setMaxListeners(n) 为单个 AbortSignal 实例设置警告限制,但默认情况下 AbortSignal 实例不会发出警告。
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));
});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') 进行检查,并将具有额外的 emitter、type 和 count 属性,分别指事件发射器实例、事件名称和附加的监听器数量。其 name 属性设置为 'MaxListenersExceededWarning'。
events.errorMonitor#
此符号应用于安装一个仅用于监视 'error' 事件的监听器。使用此符号安装的监听器在常规 'error' 监听器被调用之前被调用。
使用此符号安装监听器不会改变一旦发出 'error' 事件后的行为。因此,如果没有安装常规的 'error' 监听器,进程仍然会崩溃。
events.getEventListeners(emitterOrTarget, eventName)#
emitterOrTarget<EventEmitter> | <EventTarget>eventName<string> | <symbol>- 返回:<Function[]>
返回名为 eventName 的事件的监听器数组的副本。
对于 EventEmitter,此行为与在发射器上调用 .listeners 完全相同。
对于 EventTarget,这是获取事件目标的事件监听器的唯一方法。这对于调试和诊断目的很有用。
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] ]
}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)#
emitterOrTarget<EventEmitter> | <EventTarget>- 返回:<number>
返回当前设置的最大监听器数量。
对于 EventEmitter,此行为与在发射器上调用 .getMaxListeners 完全相同。
对于 EventTarget,这是获取事件目标的最大事件监听器数量的唯一方法。如果单个 EventTarget 上的事件处理程序数量超过了设置的最大值,EventTarget 将打印一个警告。
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
}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])#
emitter<EventEmitter>name<string> | <symbol>options<Object>signal<AbortSignal> 可用于取消等待事件。
- 返回:<Promise>
创建一个 Promise,当 EventEmitter 发出给定事件时,该 Promise 会被兑现;或者如果在等待期间 EventEmitter 发出 'error',则该 Promise 会被拒绝。该 Promise 将以一个包含所有传递给给定事件的参数的数组来解决。
此方法特意设计为通用的,并且适用于 Web 平台的 EventTarget 接口,该接口没有特殊的 'error' 事件语义,并且不监听 'error' 事件。
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);
}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();
对 'error' 事件的特殊处理仅在 events.once() 用于等待另一个事件时使用。如果 events.once() 用于等待 'error' 事件本身,那么它将被视为任何其他类型的事件,没有特殊处理。
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 boomconst { 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> 来取消等待事件。
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!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() 可能会错过一个事件。
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');
// This Promise will never resolve because the 'foo' event will
// have already been emitted before the Promise is created.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));const { EventEmitter, once } = require('node:events');
const myEE = new EventEmitter();
async function foo() {
await once(myEE, 'bar');
console.log('bar');
// This Promise will never resolve because the 'foo' event will
// have already been emitted before the Promise is created.
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));
要捕获这两个事件,请在等待任何一个 Promise 之前创建每个 Promise,然后就可以使用 Promise.all()、Promise.race() 或 Promise.allSettled()。
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'));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#
- 类型:<boolean>
更改所有新 EventEmitter 对象上的默认 captureRejections 选项。
events.captureRejectionSymbol#
- 类型:<symbol>
Symbol.for('nodejs.rejection')
参见如何编写自定义拒绝处理程序。
events.listenerCount(emitter, eventName)#
emitter.listenerCount()。emitter<EventEmitter> 要查询的发射器eventName<string> | <symbol> 事件名称
一个类方法,返回在给定 emitter 上为给定 eventName 注册的监听器数量。
import { EventEmitter, listenerCount } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2const { EventEmitter, listenerCount } = require('node:events');
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2
events.on(emitter, eventName[, options])#
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事件
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable hereconst { on, EventEmitter } = require('node:events');
(async () => {
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable here
})();
返回一个迭代 eventName 事件的 AsyncIterator。如果 EventEmitter 发出 'error',它将抛出错误。当退出循环时,它会移除所有监听器。每次迭代返回的 value 是一个由发出的事件参数组成的数组。
可以使用 <AbortSignal> 来取消对事件的等待。
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable here
})();
process.nextTick(() => ac.abort());const { on, EventEmitter } = require('node:events');
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable here
})();
process.nextTick(() => ac.abort());
events.setMaxListeners(n[, ...eventTargets])#
n<number> 一个非负数。每个EventTarget事件的最大监听器数。...eventsTargets<EventTarget[]> | <EventEmitter[]> 零个或多个 <EventTarget> 或 <EventEmitter> 实例。如果未指定,n将被设置为所有新创建的 <EventTarget> 和 <EventEmitter> 对象的默认最大值。
import { setMaxListeners, EventEmitter } from 'node:events';
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);const {
setMaxListeners,
EventEmitter,
} = require('node:events');
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);
events.addAbortListener(signal, listener)#
signal<AbortSignal>listener<Function> | <EventListener>- 返回:<Disposable> 一个移除
abort监听器的 Disposable 对象。
在提供的 signal 上监听一次 abort 事件。
在中止信号上监听 abort 事件是不安全的,可能会导致资源泄漏,因为拥有该信号的第三方可以调用 e.stopImmediatePropagation()。不幸的是,Node.js 无法改变这一点,因为这会违反 Web 标准。此外,原始 API 很容易让人忘记移除监听器。
此 API 通过以一种方式监听事件,使得 stopImmediatePropagation 不会阻止监听器运行,从而解决了这两个问题,允许在 Node.js API 中安全地使用 AbortSignal。
返回一个 disposable 对象,以便可以更容易地取消订阅。
const { addAbortListener } = require('node:events');
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}import { addAbortListener } from 'node:events';
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}
类:events.EventEmitterAsyncResource extends EventEmitter#
将 EventEmitter 与 <AsyncResource> 集成,用于需要手动异步跟踪的 EventEmitter。具体来说,由 events.EventEmitterAsyncResource 实例发出的所有事件都将在其异步上下文中运行。
import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
import { notStrictEqual, strictEqual } from 'node:assert';
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
// Async tracking tooling will identify this as 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// 'foo' listeners will run in the EventEmitters async context.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// 'foo' listeners on ordinary EventEmitters that do not track async
// context, however, run in the same async context as the emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});const { EventEmitterAsyncResource, EventEmitter } = require('node:events');
const { notStrictEqual, strictEqual } = require('node:assert');
const { executionAsyncId, triggerAsyncId } = require('node:async_hooks');
// Async tracking tooling will identify this as 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// 'foo' listeners will run in the EventEmitters async context.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// 'foo' listeners on ordinary EventEmitters that do not track async
// context, however, run in the same async context as the emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});
EventEmitterAsyncResource 类具有与 EventEmitter 和 AsyncResource 自身相同的方法和选项。
new events.EventEmitterAsyncResource([options])#
options<Object>captureRejections<boolean> 它启用自动捕获 promise 拒绝。默认值:false。name<string> 异步事件的类型。默认值:new.target.name。triggerAsyncId<number> 创建此异步事件的执行上下文的 ID。默认值:executionAsyncId()。requireManualDestroy<boolean> 如果设置为true,则在对象被垃圾回收时禁用emitDestroy。通常不需要设置此项(即使手动调用emitDestroy),除非检索了资源的asyncId并使用它调用了敏感 API 的emitDestroy。当设置为false时,仅当至少有一个活动的destroy钩子时,垃圾回收时的emitDestroy调用才会发生。默认值:false。
eventemitterasyncresource.asyncResource#
- 类型:<AsyncResource> 底层的 <AsyncResource>。
返回的 AsyncResource 对象有一个额外的 eventEmitter 属性,提供了对此 EventEmitterAsyncResource 的引用。
eventemitterasyncresource.emitDestroy()#
调用所有 destroy 钩子。这应该只被调用一次。如果调用超过一次,将抛出错误。这必须手动调用。如果资源被垃圾回收器收集,destroy 钩子将永远不会被调用。
EventTarget 和 Event API#
EventTarget 和 Event 对象是 EventTarget Web API 的 Node.js 特定实现,由一些 Node.js 核心 API 公开。
const target = new EventTarget();
target.addEventListener('foo', (event) => {
console.log('foo event happened!');
});
Node.js EventTarget 与 DOM EventTarget 的对比#
Node.js EventTarget 和 EventTarget Web API 之间有两个关键区别:
- 虽然 DOM
EventTarget实例可能是分层的,但在 Node.js 中没有层次结构和事件传播的概念。也就是说,分派到EventTarget的事件不会通过嵌套的目标对象层次结构传播,而这些对象可能各自拥有自己的一组事件处理程序。 - 在 Node.js
EventTarget中,如果事件监听器是一个异步函数或返回一个Promise,并且返回的Promise被拒绝,则该拒绝会被自动捕获并以与同步抛出错误的监听器相同的方式处理(详情请参见EventTarget错误处理)。
NodeEventTarget 与 EventEmitter 的对比#
NodeEventTarget 对象实现了 EventEmitter API 的一个修改子集,使其能够在某些情况下紧密地模拟 EventEmitter。NodeEventTarget 不是 EventEmitter 的实例,在大多数情况下不能替代 EventEmitter 使用。
- 与
EventEmitter不同,任何给定的listener对于每个事件type最多只能注册一次。多次尝试注册同一个listener会被忽略。 NodeEventTarget不模拟完整的EventEmitterAPI。具体来说,prependListener()、prependOnceListener()、rawListeners()和errorMonitorAPI 不被模拟。'newListener'和'removeListener'事件也不会被发出。NodeEventTarget没有为类型为'error'的事件实现任何特殊的默认行为。NodeEventTarget支持将EventListener对象以及函数作为所有事件类型的处理程序。
事件监听器#
为事件 type 注册的事件监听器可以是 JavaScript 函数,也可以是具有 handleEvent 属性的对象,该属性的值是一个函数。
无论哪种情况,处理函数都会被调用,并传入传递给 eventTarget.dispatchEvent() 函数的 event 参数。
异步函数可以用作事件监听器。如果一个异步处理函数被拒绝,该拒绝将被捕获并按照 EventTarget 错误处理 中描述的方式处理。
一个处理函数抛出的错误不会阻止其他处理函数被调用。
处理函数的返回值被忽略。
处理程序总是按照它们被添加的顺序被调用。
处理函数可能会修改 event 对象。
function handler1(event) {
console.log(event.type); // Prints 'foo'
event.a = 1;
}
async function handler2(event) {
console.log(event.type); // Prints 'foo'
console.log(event.a); // Prints 1
}
const handler3 = {
handleEvent(event) {
console.log(event.type); // Prints 'foo'
},
};
const handler4 = {
async handleEvent(event) {
console.log(event.type); // Prints '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('error') 事件,然后才到达 process.on('uncaughtException')。此行为已被弃用,并将在未来版本中更改,以使 EventTarget 与其他 Node.js API 保持一致。任何依赖 process.on('error') 事件的代码都应与新行为保持一致。
类:Event#
Event 对象是 Event Web API 的一个改编版。实例由 Node.js 内部创建。
event.cancelBubble#
event.stopPropagation()。- 类型:<boolean>
如果设置为 true,则是 event.stopPropagation() 的别名。这在 Node.js 中未使用,提供它纯粹是为了完整性。
event.composedPath()#
返回一个包含当前 EventTarget 作为唯一条目的数组,如果事件未被分派,则返回空数组。这在 Node.js 中未使用,提供它纯粹是为了完整性。
event.initEvent(type[, bubbles[, cancelable]])#
与事件构造函数功能重复,且无法设置 composed。这在 Node.js 中未使用,提供它纯粹是为了完整性。
event.preventDefault()#
如果 cancelable 为 true,则将 defaultPrevented 属性设置为 true。
event.returnValue#
event.defaultPrevented。- 类型:<boolean> 如果事件未被取消,则为 True。
event.returnValue 的值始终与 event.defaultPrevented 相反。这在 Node.js 中未使用,提供它纯粹是为了完整性。
event.srcElement#
event.target。- 类型:<EventTarget> 分派事件的
EventTarget。
event.target 的别名。
event.stopImmediatePropagation()#
在当前监听器完成后,停止调用后续的事件监听器。
event.stopPropagation()#
这在 Node.js 中未使用,提供它纯粹是为了完整性。
event.target#
- 类型:<EventTarget> 分派事件的
EventTarget。
类:EventTarget#
eventTarget.addEventListener(type, listener[, options])#
type<string>listener<Function> | <EventListener>options<Object>once<boolean> 当为true时,监听器在首次调用后会自动移除。默认值:false。passive<boolean> 当为true时,作为监听器不会调用Event对象的preventDefault()方法的提示。默认值:false。capture<boolean> 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。
function handler(event) {}
const target = new EventTarget();
target.addEventListener('foo', handler, { capture: true }); // first
target.addEventListener('foo', handler, { capture: false }); // second
// Removes the second instance of handler
target.removeEventListener('foo', handler);
// Removes the first instance of handler
target.removeEventListener('foo', handler, { capture: true });
eventTarget.dispatchEvent(event)#
event<Event>- 返回:<boolean> 如果事件的
cancelable属性值为 false 或其preventDefault()方法未被调用,则为true,否则为false。
将 event 分派给 event.type 的处理程序列表。
注册的事件监听器会按照它们注册的顺序同步调用。
eventTarget.removeEventListener(type, listener[, options])#
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
从事件 type 的处理程序列表中移除 listener。
类:NodeEventTarget#
NodeEventTarget 是 EventTarget 的一个 Node.js 特定扩展,它模拟了 EventEmitter API 的一个子集。
nodeEventTarget.addListener(type, listener)#
-
type<string> -
listener<Function> | <EventListener> -
返回:<EventTarget> this
EventTarget 类的 Node.js 特定扩展,模拟了等效的 EventEmitter API。addListener() 和 addEventListener() 之间的唯一区别是 addListener() 会返回对 EventTarget 的引用。
nodeEventTarget.emit(type, arg)#
EventTarget 类的 Node.js 特定扩展,将 arg 分派给 type 的处理程序列表。
nodeEventTarget.eventNames()#
- 返回:<string[]>
EventTarget 类的 Node.js 特定扩展,返回一个事件 type 名称的数组,这些事件已注册了监听器。
nodeEventTarget.listenerCount(type)#
EventTarget 类的 Node.js 特定扩展,返回为 type 注册的事件监听器数量。
nodeEventTarget.off(type, listener[, options])#
-
type<string> -
listener<Function> | <EventListener> -
options<Object>capture<boolean>
-
返回:<EventTarget> this
eventTarget.removeEventListener() 的 Node.js 特定别名。
nodeEventTarget.on(type, listener)#
-
type<string> -
listener<Function> | <EventListener> -
返回:<EventTarget> this
eventTarget.addEventListener() 的 Node.js 特定别名。
nodeEventTarget.once(type, listener)#
-
type<string> -
listener<Function> | <EventListener> -
返回:<EventTarget> this
EventTarget 类的 Node.js 特定扩展,为给定的事件 type 添加一个 once 监听器。这等同于调用 on 并将 once 选项设置为 true。
nodeEventTarget.removeAllListeners([type])#
-
type<string> -
返回:<EventTarget> this
EventTarget 类的 Node.js 特定扩展。如果指定了 type,则移除所有为 type 注册的监听器,否则移除所有已注册的监听器。
nodeEventTarget.removeListener(type, listener[, options])#
-
type<string> -
listener<Function> | <EventListener> -
options<Object>capture<boolean>
-
返回:<EventTarget> this
EventTarget 类的 Node.js 特定扩展,为给定的 type 移除 listener。removeListener() 和 removeEventListener() 之间的唯一区别是 removeListener() 会返回对 EventTarget 的引用。