Node.js v21.7.2 ドキュメント
- Node.js v21.7.2
-
► 目次
- イベント
- リスナーへの引数と
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.defaultMaxListeners
events.errorMonitor
events.getEventListeners(emitterOrTarget, eventName)
events.getMaxListeners(emitterOrTarget)
events.once(emitter, name[, options])
events.captureRejections
events.captureRejectionSymbol
events.listenerCount(emitter, eventName)
events.on(emitter, eventName[, options])
events.setMaxListeners(n[, ...eventTargets])
events.addAbortListener(signal, listener)
- クラス:
events.EventEmitterAsyncResource extends EventEmitter
EventTarget
とEvent
API- Node.js
EventTarget
vs. DOMEventTarget
NodeEventTarget
vs.EventEmitter
- イベントリスナー
EventTarget
エラー処理- クラス:
Event
event.bubbles
event.cancelBubble
event.cancelable
event.composed
event.composedPath()
event.currentTarget
event.defaultPrevented
event.eventPhase
event.initEvent(type[, bubbles[, cancelable]])
event.isTrusted
event.preventDefault()
event.returnValue
event.srcElement
event.stopImmediatePropagation()
event.stopPropagation()
event.target
event.timeStamp
event.type
- クラス: `EventTarget`
- クラス:
CustomEvent
- クラス:
NodeEventTarget
nodeEventTarget.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
- 子プロセス
- クラスタ
- コマンドラインオプション
- コンソール
- Corepack
- 暗号
- デバッガ
- 非推奨 API
- 診断チャネル
- DNS
- ドメイン
- エラー
- イベント
- ファイルシステム
- グローバル
- HTTP
- HTTP/2
- HTTPS
- インスペクタ
- 国際化
- モジュール: CommonJS モジュール
- モジュール: ECMAScript モジュール
- モジュール:
node:module
API - モジュール: パッケージ
- Net
- OS
- パス
- パフォーマンスフック
- パーミッション
- プロセス
- Punycode
- クエリ文字列
- Readline
- REPL
- レポート
- 単一実行可能アプリケーション
- ストリーム
- 文字列デコーダ
- テストランナー
- タイマー
- TLS/SSL
- トレースイベント
- TTY
- UDP/データグラム
- URL
- ユーティリティ
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- ワーカースレッド
- Zlib
- ► 他のバージョン
- ► オプション
イベント#
ソースコード: lib/events.js
Node.js コア API の多くは、特定の種類のオブジェクト(「エミッター」と呼ばれる)が名前付きイベントを発行し、それによって Function
オブジェクト(「リスナー」)が呼び出される、慣用的な非同期イベント駆動アーキテクチャに基づいて構築されています。
たとえば、net.Server
オブジェクトは、ピアが接続するたびにイベントを発行します。fs.ReadStream
は、ファイルが開かれたときにイベントを発行します。ストリーム は、データが読み取り可能になるたびにイベントを発行します。
イベントを発行するすべてのオブジェクトは、EventEmitter
クラスのインスタンスです。これらのオブジェクトは、オブジェクトによって発行された名前付きイベントに1つ以上の関数をアタッチできる 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: 2
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');
// Prints: 1
myEmitter.emit('event');
// Prints: 2
eventEmitter.once()
メソッドを使用すると、特定のイベントに対して最大1回呼び出されるリスナーを登録できます。イベントが発行されると、リスナーの登録が解除され、*その後*呼び出されます。
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');
// Ignored
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');
// Prints: 1
myEmitter.emit('event');
// Ignored
エラーイベント#
EventEmitter
インスタンス内でエラーが発生した場合、一般的なアクションは `'error'` イベントが発行されることです。これらは Node.js 内で特別なケースとして扱われます。
EventEmitter
に `'error'` イベントのリスナーが少なくとも1つ登録されておらず、`'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.js
const 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 error
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!'));
// 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.js
const { 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'` イベントには、無限エラーループを回避するための catch ハンドラがありません。推奨事項は、**`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
// A
const 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
<string> | <symbol>...args
<any>- 戻り値: <boolean>
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 listener
const 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()
#
- 戻り値: <Array>
エミッターがリスナーを登録しているイベントをリストした配列を返します。配列の値は文字列または 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>
emitter.setMaxListeners(n)
によって設定されるか、events.defaultMaxListeners
にデフォルト設定される、EventEmitter
の現在の最大リスナー値を返します。
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.removeListener()
のエイリアスです。
emitter.on(eventName, listener)
#
eventName
<string> | <symbol> イベントの名前。listener
<Function> コールバック関数- 戻り値: <EventEmitter>
eventName
という名前のイベントのリスナー配列の末尾に listener
関数を追加します。 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
// a
const 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
// a
const 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>
eventName
という名前のイベントのリスナー配列の*先頭*に listener
関数を追加します。 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()
は、リスナー配列からリスナーのインスタンスを最大で 1 つ削除します。単一のリスナーが指定された 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:
// A
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 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])
#
err
エラーeventName
<string> | <symbol>...args
<any>
Symbol.for('nodejs.rejection')
メソッドは、イベントの発行時に Promise の拒否が発生し、エミッターで captureRejections
が有効になっている場合に呼び出されます。 Symbol.for('nodejs.rejection')
の代わりに events.captureRejectionSymbol
を使用できます。
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
がスローされます。
変更前に作成されたインスタンスを含め、*すべて*の EventEmitter
インスタンスに影響を与えるため、events.defaultMaxListeners
を設定するときは注意が必要です。ただし、emitter.setMaxListeners(n)
を呼び出すと、events.defaultMaxListeners
よりも優先されます。
これは厳密な制限ではありません。 EventEmitter
インスタンスは、さらに多くのリスナーを追加することを許可しますが、「EventEmitter メモリリークの可能性あり」が検出されたことを示すトレース警告を stderr に出力します。単一の EventEmitter
については、emitter.getMaxListeners()
および emitter.setMaxListeners()
メソッドを使用して、この警告を一時的に回避できます。
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>options
<Object>signal
<AbortSignal> イベントの待機をキャンセルするために使用できます。
- 戻り値: <Promise>
EventEmitter
が指定されたイベントを発行したときに履行されるか、待機中に EventEmitter
が 'error'
を発行したときに拒否される Promise
を作成します。Promise
は、指定されたイベントに発行されたすべての引数の配列で解決されます。
このメソッドは意図的に汎用的であり、特別な 'error'
イベントセマンティクスを持たず、'error'
イベントをリッスンしない Web プラットフォームの EventTarget インターフェースと連携します。
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 boom
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> を使用して、イベントの待機をキャンセルできます。
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(); // Abort waiting for the event
ee.emit('foo'); // 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(); // Abort waiting for the event
ee.emit('foo'); // 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.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.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: 2
const { 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> イベントの待機をキャンセルするために使用できます。
- 戻り値:
emitter
によって発行されたeventName
イベントを反復処理する <AsyncIterator>
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 here
const { 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` がリスナーの実行を妨げないようイベントをリッスンすることで、これら 2 つの問題を解決し、Node.js API で `AbortSignal` を安全に使用できます。
より簡単に登録解除できるように、使い捨てオブジェクトを返します。
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
のために、EventEmitter
を <AsyncResource> と統合します。具体的には、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
が無効になります。これは通常、リソースの `asyncId` が取得され、機密性の高い API の `emitDestroy` がそれで呼び出されない限り、設定する必要はありません (`emitDestroy` が手動で呼び出される場合でも)。`false` に設定すると、ガベージコレクション時の `emitDestroy` 呼び出しは、少なくとも 1 つのアクティブな `destroy` フックがある場合にのみ行われます。**デフォルト:**false
。
eventemitterasyncresource.asyncId
#
- タイプ: <number> リソースに割り当てられた一意の
asyncId
。
eventemitterasyncresource.asyncResource
#
- タイプ: 基礎となる <AsyncResource>。
返された AsyncResource
オブジェクトには、この EventEmitterAsyncResource
への参照を提供する追加の eventEmitter
プロパティがあります。
eventemitterasyncresource.emitDestroy()
#
すべての destroy
フックを呼び出します。これは一度だけ呼び出す必要があります。複数回呼び出されるとエラーがスローされます。これは手動で呼び出す*必要*があります。リソースが GC によって収集されるままになっている場合、`destroy` フックは呼び出されません。
eventemitterasyncresource.triggerAsyncId
#
- タイプ: <number>
AsyncResource
コンストラクターに渡されるのと同じtriggerAsyncId
。
EventTarget
および Event
API#
EventTarget
オブジェクトと Event
オブジェクトは、一部の Node.js コア API によって公開される EventTarget
Web API の Node.js 固有の実装です。
const target = new EventTarget();
target.addEventListener('foo', (event) => {
console.log('foo event happened!');
});
Node.js の EventTarget
と DOM の EventTarget
の比較#
Node.js の EventTarget
と EventTarget
Web API には、2 つの重要な違いがあります。
- DOM の
EventTarget
インスタンスは階層的である場合がありますが、Node.js には階層とイベント伝播の概念はありません。つまり、EventTarget
にディスパッチされたイベントは、それぞれ独自のイベントハンドラセットを持つ可能性のあるネストされたターゲットオブジェクトの階層を伝播しません。 - Node.js の
EventTarget
では、イベントリスナーが async 関数であるかPromise
を返す場合、返されたPromise
が拒否されると、拒否は自動的に捕捉され、同期的にスローするリスナーと同じ方法で処理されます(詳細はEventTarget
エラー処理 を参照)。
NodeEventTarget
と EventEmitter
の比較#
NodeEventTarget
オブジェクトは、特定の状況で EventEmitter
を厳密に *エミュレート* できるようにする、EventEmitter
API の変更されたサブセットを実装します。 NodeEventTarget
は EventEmitter
のインスタンスではなく、ほとんどの場合、EventEmitter
の代わりに使用することはできません。
EventEmitter
とは異なり、任意のlistener
はイベントtype
ごとに最大 1 回だけ登録できます。listener
を複数回登録しようとすると無視されます。NodeEventTarget
は、完全なEventEmitter
API をエミュレートしません。具体的には、prependListener()
、prependOnceListener()
、rawListeners()
、およびerrorMonitor
API はエミュレートされません。'newListener'
イベントと'removeListener'
イベントも発行されません。NodeEventTarget
は、タイプ'error'
のイベントに対して特別なデフォルトの動作を実装しません。NodeEventTarget
は、すべてのイベントタイプのハンドラとして、関数だけでなくEventListener
オブジェクトもサポートします。
イベントリスナー#
イベント type
に登録されたイベントリスナーは、JavaScript 関数または値が関数である handleEvent
プロパティを持つオブジェクトのいずれかです。
いずれの場合も、ハンドラ関数は eventTarget.dispatchEvent()
関数に渡された event
引数を使用して呼び出されます。
Async 関数はイベントリスナーとして使用できます。非同期ハンドラ関数が拒否された場合、拒否は捕捉され、EventTarget
エラー処理 で説明されているように処理されます。
1 つのハンドラ関数によってスローされたエラーは、他のハンドラが呼び出されるのを妨げません。
ハンドラ関数の戻り値は無視されます。
ハンドラは常に追加された順序で呼び出されます。
ハンドラ関数は 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('uncaughtException')
に到達する前に、最初に process.on('error')
イベントに転送されます。この動作は非推奨であり、将来のリリースで EventTarget
を他の Node.js API と連携させるために変更されます。 process.on('error')
イベントに依存するコードは、新しい動作に合わせて調整する必要があります。
クラス: Event
#
Event
オブジェクトは、Event
Web API を改変したものです。インスタンスは Node.js によって内部的に作成されます。
event.bubbles
#
- タイプ: <boolean> 常に
false
を返します。
これは Node.js では使用されず、完全性のためにのみ提供されています。
event.cancelBubble
#
event.stopPropagation()
を使用してください。- タイプ: <boolean>
true
に設定されている場合、event.stopPropagation()
のエイリアスです。これは Node.js では使用されず、完全性のためにのみ提供されています。
event.cancelable
#
- タイプ: <boolean> イベントが
cancelable
オプションで作成された場合は true です。
event.composed
#
- タイプ: <boolean> 常に
false
を返します。
これは Node.js では使用されず、完全性のためにのみ提供されています。
event.composedPath()
#
現在の EventTarget
のみをエントリとして含む配列を返します。イベントがディスパッチされていない場合は空の配列を返します。これは Node.js では使用されず、完全性のためにのみ提供されています。
event.currentTarget
#
- タイプ: <EventTarget> イベントをディスパッチする
EventTarget
です。
event.target
のエイリアスです。
event.defaultPrevented
#
- タイプ: <boolean>
cancelable
が true
で、event.preventDefault()
が呼び出されている場合は true
です。
event.eventPhase
#
- タイプ: <number> イベントがディスパッチされていない間は
0
を返し、ディスパッチされている間は2
を返します。
これは Node.js では使用されず、完全性のためにのみ提供されています。
event.initEvent(type[, bubbles[, cancelable]])
#
イベントコンストラクタと冗長であり、composed
を設定できません。これは Node.js では使用されず、完全性のためにのみ提供されています。
event.isTrusted
#
- タイプ: <boolean>
<AbortSignal> "abort"
イベントは、isTrusted
が true
に設定されて発行されます。その他のすべての場合、値は false
です。
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
です。
event.timeStamp
#
- タイプ: <number>
Event
オブジェクトが作成されたミリ秒単位のタイムスタンプです。
event.type
#
- タイプ: <string>
イベントタイプ識別子です。
クラス: 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
の場合、listener
は次回 type
イベントがディスパッチされた後に削除されます。
capture
オプションは、EventTarget
仕様に従って登録されたイベントリスナーを追跡する以外、Node.js では機能的に使用されません。具体的には、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
を削除します。
クラス: CustomEvent
#
- 継承元: <Event>
CustomEvent
オブジェクトは、CustomEvent
Web API を Node.js向けに適用したものです。インスタンスは Node.js によって内部的に作成されます。
event.detail
#
- 型: <any> 初期化時に渡されたカスタムデータを返します。
読み取り専用。
クラス: NodeEventTarget
#
- 継承元: <EventTarget>
NodeEventTarget
は、EventEmitter
API のサブセットをエミュレートする、Node.js 独自の EventTarget
拡張です。
nodeEventTarget.addListener(type, listener)
#
-
type
<string> -
listener
<Function> | <EventListener> -
戻り値: <EventTarget> this
EventEmitter
API と同等の機能をエミュレートする、Node.js 独自の EventTarget
クラス拡張です。 addListener()
と addEventListener()
の唯一の違いは、addListener()
が EventTarget
への参照を返すことです。
nodeEventTarget.emit(type, arg)
#
arg
を type
のハンドラーリストにディスパッチする、Node.js 独自の EventTarget
クラス拡張です。
nodeEventTarget.eventNames()
#
- 戻り値: <string[]>
イベントリスナーが登録されているイベント type
名の配列を返す、Node.js 独自の EventTarget
クラス拡張です。
nodeEventTarget.listenerCount(type)
#
type
に登録されているイベントリスナーの数を返す、Node.js 独自の EventTarget
クラス拡張です。
nodeEventTarget.setMaxListeners(n)
#
n
<number>
最大イベントリスナー数を n
に設定する、Node.js 独自の EventTarget
クラス拡張です。
nodeEventTarget.getMaxListeners()
#
- 戻り値: <number>
最大イベントリスナーの数を返す、Node.js 独自の EventTarget
クラス拡張です。
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
指定されたイベント type
に対して once
リスナーを追加する、Node.js 独自の EventTarget
クラス拡張です。これは、once
オプションを true
に設定して on
を呼び出すことと同じです。
nodeEventTarget.removeAllListeners([type])
#
-
type
<string> -
戻り値: <EventTarget> this
Node.js 独自の EventTarget
クラス拡張です。 type
が指定されている場合、type
のすべての登録済みリスナーを削除します。そうでない場合は、すべての登録済みリスナーを削除します。
nodeEventTarget.removeListener(type, listener[, options])
#
-
type
<string> -
listener
<Function> | <EventListener> -
options
<Object>capture
<boolean>
-
戻り値: <EventTarget> this
指定された type
の listener
を削除する、Node.js 独自の EventTarget
クラス拡張です。 removeListener()
と removeEventListener()
の唯一の違いは、removeListener()
が EventTarget
への参照を返すことです。