イベント
ソースコード: lib/events.js
Node.js コア API の多くは、特定の種類のオブジェクト(「エミッター」と呼ばれる)が名前付きイベントを発行し、それによって Function オブジェクト(「リスナー」)が呼び出されるという、慣用的な非同期イベント駆動アーキテクチャに基づいて構築されています。
例えば、net.Server オブジェクトは、ピアが接続するたびにイベントを発行します。fs.ReadStream は、ファイルが開かれたときにイベントを発行します。 stream は、読み取り可能なデータがあるたびにイベントを発行します。
イベントを発行するすべてのオブジェクトは、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: 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: 2eventEmitter.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'イベントに対して少なくとも1つのリスナーを登録 していない 場合、'error'イベントが発火されると、エラーがスローされ、スタックトレースが出力され、Node.jsプロセスが終了します。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// スローされ、Node.jsがクラッシュしますconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// スローされ、Node.jsがクラッシュしますNode.jsプロセスのクラッシュを防ぐために、domainモジュールを使用できます。(ただし、node:domainモジュールは非推奨になっていることに注意してください。)
ベストプラクティスとして、'error'イベントに対して常にリスナーを追加する必要があります。
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!'));
// それでもスローされ、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!'));
// それでもスローされ、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
[履歴]
| バージョン | 変更 |
|---|---|
| v13.4.0, v12.16.0 | captureRejections オプションが追加されました。 |
| v0.1.26 | 追加: v0.1.26 |
EventEmitter クラスは node:events モジュールによって定義され、公開されています。
import { EventEmitter } from 'node:events';const EventEmitter = require('node:events');すべての EventEmitter は、新しいリスナーが追加されると 'newListener' イベントを発行し、既存のリスナーが削除されると 'removeListener' イベントを発行します。
以下のオプションをサポートしています。
captureRejections<boolean> Promise のリジェクトの自動キャプチャを有効にします。 デフォルト:false。
イベント: 'newListener'
追加: v0.1.26
eventName<string> | <symbol> リッスンされるイベントの名前listener<Function> イベントハンドラ関数
EventEmitter インスタンスは、リスナーがリスナーの内部配列に追加される前に、独自の 'newListener' イベントを発行します。
'newListener' イベントに登録されたリスナーには、イベント名と、追加されるリスナーへの参照が渡されます。
イベントがリスナーの追加前にトリガーされるという事実は、微妙ですが重要な副作用があります。 'newListener' コールバック内で同じ name に登録された追加のリスナーは、追加処理中のリスナーの前に挿入されます。
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// ループしないように一度だけ実行します
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// 前に新しいリスナーを挿入します
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// ループしないように一度だけ実行します
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// 前に新しいリスナーを挿入します
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// Aイベント: 'removeListener'
[履歴]
| バージョン | 変更点 |
|---|---|
| v6.1.0, v4.7.0 | .once() を使ってアタッチされたリスナーに対して、listener 引数は元のリスナー関数を生成するようになりました。 |
| v0.9.3 | 追加: v0.9.3 |
eventName<string> | <symbol> イベント名listener<Function> イベントハンドラ関数
'removeListener' イベントは、listener が削除された 後 に発生します。
emitter.addListener(eventName, listener)
追加: v0.1.26
eventName<string> | <symbol>listener<Function>
emitter.on(eventName, listener) のエイリアスです。
emitter.emit(eventName[, ...args])
追加: v0.1.26
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 listeneremitter.eventNames()
Added in: v6.0.0
- 戻り値: <Array>
emitter がリスナーを登録しているイベントをリストした配列を返します。配列の値は、文字列または 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()
Added in: v1.0.0
- 戻り値: <integer>
EventEmitter の現在の最大リスナー値を返します。これは、emitter.setMaxListeners(n) によって設定されるか、デフォルトで events.defaultMaxListeners になります。
emitter.listenerCount(eventName[, listener])
[History]
| Version | Changes |
|---|---|
| v19.8.0, v18.16.0 | listener 引数が追加されました。 |
| v3.2.0 | Added in: v3.2.0 |
eventName<string> | <symbol> リッスンしているイベントの名前listener<Function> イベントハンドラー関数- 戻り値: <integer>
eventName という名前のイベントをリッスンしているリスナーの数を返します。listener が提供されている場合は、イベントのリスナーのリストでリスナーが見つかった回数を返します。
emitter.listeners(eventName)
[履歴]
| バージョン | 変更 |
|---|---|
| v7.0.0 | .once() を使用してアタッチされたリスナーの場合、ラッパー関数の代わりに元のリスナーが返されるようになりました。 |
| v0.1.26 | Added in: v0.1.26 |
eventName<string> | <symbol>- 戻り値: <Function[]>
eventName という名前のイベントのリスナーの配列のコピーを返します。
server.on('connection', (stream) => {
console.log('誰かが接続しました!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]emitter.off(eventName, listener)
Added in: v10.0.0
eventName<string> | <symbol>listener<Function>- 戻り値: <EventEmitter>
emitter.removeListener() のエイリアスです。
emitter.on(eventName, listener)
Added in: v0.1.101
eventName<string> | <symbol> イベントの名前。listener<Function> コールバック関数- 戻り値: <EventEmitter>
listener 関数を、eventName という名前のイベントのリスナー配列の末尾に追加します。 listener が既に追加されているかどうかを確認するためのチェックは行われません。 同じ eventName と listener の組み合わせを渡す複数の呼び出しは、listener が複数回追加され、呼び出される結果になります。
server.on('connection', (stream) => {
console.log('誰かが接続しました!');
});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
// aemitter.once(eventName, listener)
Added in: v0.3.0
eventName<string> | <symbol> イベントの名前。listener<Function> コールバック関数- 戻り値: <EventEmitter>
eventNameという名前のイベントに対して1回限りのlistener関数を追加します。次にeventNameがトリガーされると、このリスナーは削除され、その後呼び出されます。
server.once('connection', (stream) => {
console.log('ああ、初めてのユーザーだ!');
});呼び出しをチェーンできるように、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
// aemitter.prependListener(eventName, listener)
Added in: v6.0.0
eventName<string> | <symbol> イベントの名前。listener<Function> コールバック関数- 戻り値: <EventEmitter>
listener関数を、eventNameという名前のイベントのリスナー配列の先頭に追加します。listenerが既に追加されているかどうかを確認するためのチェックは行われません。同じeventNameとlistenerの組み合わせを渡して複数回呼び出すと、listenerが複数回追加され、呼び出されます。
server.prependListener('connection', (stream) => {
console.log('誰かが接続しました!');
});呼び出しをチェーンできるように、EventEmitterへの参照を返します。
emitter.prependOnceListener(eventName, listener)
Added in: v6.0.0
eventName<string> | <symbol> イベントの名前。listener<Function> コールバック関数- 戻り値: <EventEmitter>
eventName という名前のイベントに対する 1 回限り の listener 関数を、リスナー配列の 先頭 に追加します。 次回 eventName がトリガーされると、このリスナーは削除され、その後呼び出されます。
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});EventEmitter への参照を返すので、呼び出しをチェーンできます。
emitter.removeAllListeners([eventName])
Added in: v0.1.26
eventName<string> | <symbol>- 戻り値: <EventEmitter>
すべてのリスナー、または指定された eventName のリスナーを削除します。
コードの別の場所で追加されたリスナーを削除すること、特に EventEmitter インスタンスが他のコンポーネントまたはモジュール (ソケットやファイルストリームなど) によって作成された場合は、望ましくありません。
EventEmitter への参照を返すので、呼び出しをチェーンできます。
emitter.removeListener(eventName, listener)
Added in: v0.1.26
eventName<string> | <symbol>listener<Function>- 戻り値: <EventEmitter>
指定された listener を、eventName という名前のイベントのリスナー配列から削除します。
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:
// 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)
追加: v0.3.5
n<integer>- 戻り値: <EventEmitter>
デフォルトでは、特定のイベントに対して 10 個を超えるリスナーが追加されると、EventEmitter は警告を出力します。これは、メモリリークを見つけるのに役立つ便利なデフォルトです。emitter.setMaxListeners() メソッドを使用すると、この特定の EventEmitter インスタンスの制限を変更できます。値は、無制限のリスナーを示すために Infinity (または 0) に設定できます。
EventEmitter への参照を返すため、呼び出しをチェーンできます。
emitter.rawListeners(eventName)
追加: v9.4.0
eventName<string> | <symbol>- 戻り値: <Function[]>
.once() で作成されたラッパーなど、eventName という名前のイベントのリスナーの配列のコピーを返します。
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// `onceWrapper` という関数を持つ新しい配列を返します。この関数には、上記でバインドされた元のリスナーを含むプロパティ `listener` があります。
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// コンソールに "log once" と出力し、`once` イベントのバインドを解除しません
logFnWrapper.listener();
// コンソールに "log once" と出力し、リスナーを削除します
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// 上記の `.on()` によってバインドされた単一の関数を持つ新しい配列を返します
const newListeners = emitter.rawListeners('log');
// "log persistently" を 2 回出力します
newListeners[0]();
emitter.emit('log');const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// `onceWrapper` という関数を持つ新しい配列を返します。この関数には、上記でバインドされた元のリスナーを含むプロパティ `listener` があります。
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// コンソールに "log once" と出力し、`once` イベントのバインドを解除しません
logFnWrapper.listener();
// コンソールに "log once" と出力し、リスナーを削除します
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// 上記の `.on()` によってバインドされた単一の関数を持つ新しい配列を返します
const newListeners = emitter.rawListeners('log');
// "log persistently" を 2 回出力します
newListeners[0]();
emitter.emit('log');emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])
[履歴]
| バージョン | 変更点 |
|---|---|
| v17.4.0, v16.14.0 | 実験的ではなくなりました。 |
| v13.4.0, v12.16.0 | 追加: v13.4.0, v12.16.0 |
Symbol.for('nodejs.rejection') メソッドは、イベントの発行時に Promise のリジェクトが発生し、captureRejections が EventEmitter で有効になっている場合に呼び出されます。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
追加: v0.11.2
デフォルトでは、単一のイベントに対して最大 10 個のリスナーを登録できます。 この制限は、emitter.setMaxListeners(n) メソッドを使用して、個々の EventEmitter インスタンスに対して変更できます。 すべての EventEmitter インスタンスのデフォルトを変更するには、events.defaultMaxListeners プロパティを使用できます。 この値が正の数でない場合は、RangeError がスローされます。
events.defaultMaxListeners を設定する際は注意してください。変更は、変更が行われる前に作成されたものを含め、すべての EventEmitter インスタンスに影響を与えるためです。 ただし、emitter.setMaxListeners(n) の呼び出しは、events.defaultMaxListeners よりも優先されます。
これはハードリミットではありません。 EventEmitter インスタンスは、より多くのリスナーの追加を許可しますが、"EventEmitter のメモリリークの可能性" が検出されたことを示すトレース警告を stderr に出力します。 単一の 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
追加: v13.6.0, v12.17.0
このシンボルは、'error' イベントのみを監視するためのリスナーをインストールするために使用されます。このシンボルを使用してインストールされたリスナーは、通常の 'error' リスナーが呼び出される前に呼び出されます。
このシンボルを使用してリスナーをインストールしても、'error' イベントが発行された後の動作は変更されません。したがって、通常の 'error' リスナーがインストールされていない場合、プロセスは引き続きクラッシュします。
events.getEventListeners(emitterOrTarget, eventName)
追加: v15.2.0, v14.17.0
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)
Added in: v19.9.0, v18.17.0
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])
[履歴]
| バージョン | 変更 |
|---|---|
| v15.0.0 | signal オプションがサポートされるようになりました。 |
| v11.13.0, v10.16.0 | Added in: v11.13.0, v10.16.0 |
emitter<EventEmitter>options<Object>signal<AbortSignal> イベントの待機をキャンセルするために使用できます。
戻り値: <Promise>
EventEmitter が指定されたイベントを発行したときに履行される Promise を作成します。または、待機中に EventEmitter が 'error' を発行した場合は拒否されます。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 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() で発生する複数のイベントの待機
process.nextTick() 操作の同じバッチ内で、または複数のイベントが同期的に発生する場合に、events.once() 関数を使用して複数のイベントを待機するときに注意すべきエッジケースがあります。具体的には、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');
// この Promise は、'foo' イベントが Promise が作成される前に
// 既に発生しているため、決して解決されません。
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');
// この Promise は、'foo' イベントが Promise が作成される前に
// 既に発生しているため、決して解決されません。
await once(myEE, 'foo');
console.log('foo');
}
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});
foo().then(() => console.log('done'));両方のイベントをキャッチするには、それらのいずれかを待機する前に、各 Promise を作成します。これにより、Promise.all()、Promise.race()、または Promise.allSettled() を使用できるようになります。
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
[履歴]
| バージョン | 変更 |
|---|---|
| v17.4.0, v16.14.0 | 実験的ではなくなりました。 |
| v13.4.0, v12.16.0 | 追加: v13.4.0, v12.16.0 |
値: <boolean>
すべての新しい EventEmitter オブジェクトのデフォルトの captureRejections オプションを変更します。
events.captureRejectionSymbol
[履歴]
| バージョン | 変更 |
|---|---|
| v17.4.0, v16.14.0 | 実験的ではなくなりました。 |
| v13.4.0, v12.16.0 | 追加: v13.4.0, v12.16.0 |
値: Symbol.for('nodejs.rejection')
カスタムのリジェクションハンドラーの書き方をご覧ください。
events.listenerCount(emitter, eventName)
追加: v0.9.12
非推奨: v3.2.0
[安定版: 0 - 非推奨]
安定版: 0 安定性: 0 - 非推奨: 代わりに emitter.listenerCount() を使用してください。
emitter<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: 2events.on(emitter, eventName[, options])
[履歴]
| バージョン | 変更 |
|---|---|
| v22.0.0, v20.13.0 | 一貫性のため、highWaterMark および lowWaterMark オプションをサポートします。 古いオプションも引き続きサポートされています。 |
| v20.0.0 | close、highWatermark、および lowWatermark オプションがサポートされるようになりました。 |
| v13.6.0, v12.16.0 | Added in: v13.6.0, v12.16.0 |
emitter<EventEmitter>options<Object>signal<AbortSignal> イベントの待機をキャンセルするために使用できます。close- <string[]> イテレーションを終了するイベントの名前。highWaterMark- <integer> デフォルト:Number.MAX_SAFE_INTEGER高水位標。 バッファリングされるイベントのサイズがこれよりも大きい場合、エミッターは毎回一時停止されます。pause()メソッドとresume()メソッドを実装するエミッターでのみサポートされます。lowWaterMark- <integer> デフォルト:1低水位標。 バッファリングされるイベントのサイズがこれよりも小さい場合、エミッターは毎回再開されます。pause()メソッドとresume()メソッドを実装するエミッターでのみサポートされます。
戻り値:
emitterによって発行されたeventNameイベントをイテレートする <AsyncIterator>
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// 後で発行
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// この内部ブロックの実行は同期的であり、
// 一度に 1 つのイベントを処理します (await を使用しても)。 使用しないでください
// 同時実行が必要な場合。
console.log(event); // prints ['bar'] [42]
}
// ここには到達できませんconst { on, EventEmitter } = require('node:events');
(async () => {
const ee = new EventEmitter();
// 後で発行
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// この内部ブロックの実行は同期的であり、
// 一度に 1 つのイベントを処理します (await を使用しても)。 使用しないでください
// 同時実行が必要な場合。
console.log(event); // prints ['bar'] [42]
}
// ここには到達できません
})();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();
// 後で発行
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// この内部ブロックの実行は同期的であり、
// 一度に 1 つのイベントを処理します (await を使用しても)。 使用しないでください
// 同時実行が必要な場合。
console.log(event); // prints ['bar'] [42]
}
// ここには到達できません
})();
process.nextTick(() => ac.abort());const { on, EventEmitter } = require('node:events');
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// 後で発行
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// この内部ブロックの実行は同期的であり、
// 一度に 1 つのイベントを処理します (await を使用しても)。 使用しないでください
// 同時実行が必要な場合。
console.log(event); // prints ['bar'] [42]
}
// ここには到達できません
})();
process.nextTick(() => ac.abort());events.setMaxListeners(n[, ...eventTargets])
追加: v15.4.0
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)
追加: v20.5.0, v18.18.0
signal<AbortSignal>listener<Function> | <EventListener>- 戻り値: <Disposable>
abortリスナーを削除するDisposable。
指定されたsignalのabortイベントを一度だけリッスンします。
AbortSignalでabortイベントをリッスンすることは安全ではなく、シグナルを持つ別のサードパーティがe.stopImmediatePropagation()を呼び出す可能性があるため、リソースリークにつながる可能性があります。残念ながら、Node.jsはWeb標準に違反するため、これを変更することはできません。さらに、元のAPIではリスナーの削除を忘れやすくなっています。
このAPIは、stopImmediatePropagationがリスナーの実行を妨げないようにイベントをリッスンすることで、これらの2つの問題を解決することにより、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
追加: v17.4.0, v16.14.0
手動の非同期追跡を必要とする EventEmitter 用に、<AsyncResource> と EventEmitter を統合します。具体的には、events.EventEmitterAsyncResource のインスタンスによって発行されるすべてのイベントは、その async context 内で実行されます。
import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
import { notStrictEqual, strictEqual } from 'node:assert';
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
// 非同期追跡ツールはこれを 'Q' として識別します。
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// 'foo' リスナーは EventEmitters の非同期コンテキストで実行されます。
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// ただし、非同期コンテキストを追跡しない通常の EventEmitters の 'foo' リスナーは、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 } from 'node:async_hooks';
// 非同期追跡ツールはこれを 'Q' として識別します。
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// 'foo' リスナーは EventEmitters の非同期コンテキストで実行されます。
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// ただし、非同期コンテキストを追跡しない通常の EventEmitters の 'foo' リスナーは、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
- Type: <number> リソースに割り当てられた一意の
asyncId。
eventemitterasyncresource.asyncResource
- Type: 基になる<AsyncResource>。
返された AsyncResource オブジェクトには、この EventEmitterAsyncResource への参照を提供する追加の eventEmitter プロパティがあります。
eventemitterasyncresource.emitDestroy()
すべての destroy フックを呼び出します。これは一度だけ呼び出す必要があります。複数回呼び出すとエラーがスローされます。これは手動で呼び出す必要があります。リソースがGCによって収集されるまで放置されると、destroy フックは決して呼び出されません。
eventemitterasyncresource.triggerAsyncId
- タイプ: <number>
AsyncResourceコンストラクターに渡されるのと同じtriggerAsyncId。
EventTarget と Event API
[履歴]
| バージョン | 変更 |
|---|---|
| v16.0.0 | EventTarget のエラー処理を変更しました。 |
| v15.4.0 | 実験的ではなくなりました。 |
| v15.0.0 | EventTarget および Event クラスがグローバル変数として利用できるようになりました。 |
| v14.5.0 | 追加: v14.5.0 |
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 には、2 つの重要な違いがあります。
NodeEventTarget と EventEmitter の比較
NodeEventTarget オブジェクトは、特定の状況で EventEmitter を厳密にエミュレートできるようにする、EventEmitter API の変更されたサブセットを実装します。 NodeEventTarget は EventEmitter のインスタンスではありません。ほとんどの場合、EventEmitter の代わりに使用することはできません。
イベントリスナー
イベント type に登録されたイベントリスナーは、JavaScript 関数、または値が関数の handleEvent プロパティを持つオブジェクトのいずれかになります。
どちらの場合も、ハンドラー関数は eventTarget.dispatchEvent() 関数に渡される event 引数を使用して呼び出されます。
非同期関数をイベントリスナーとして使用できます。 非同期ハンドラー関数が拒否された場合、拒否はキャプチャされ、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('error') イベントに転送されてから、process.on('uncaughtException') に到達します。この動作は非推奨であり、将来のリリースで EventTarget を他の Node.js API と整合するように変更されます。process.on('error') イベントに依存するすべてのコードは、新しい動作に合わせて調整する必要があります。
Class: Event
[履歴]
| バージョン | 変更 |
|---|---|
| v15.0.0 | Event クラスがグローバルオブジェクトを通じて利用可能になりました。 |
| v14.5.0 | 追加: v14.5.0 |
Event オブジェクトは、Event Web API の適応です。インスタンスは Node.js によって内部的に作成されます。
event.bubbles
追加: v14.5.0
- 型: <boolean> 常に
falseを返します。
これは Node.js では使用されず、完全性のためだけに提供されています。
event.cancelBubble
追加: v14.5.0
[安定版: 3 - レガシー]
安定版: 3 安定度: 3 - レガシー: 代わりに event.stopPropagation() を使用してください。
- 型: <boolean>
true に設定されている場合、event.stopPropagation() のエイリアスです。これは Node.js では使用されず、完全性のためだけに提供されています。
event.cancelable
追加: v14.5.0
- 型: <boolean> イベントが
cancelableオプションを使用して作成された場合は true。
event.composed
Added in: v14.5.0
- Type: <boolean> 常に
falseを返します。
これはNode.jsでは使用されず、完全を期すためにのみ提供されています。
event.composedPath()
Added in: v14.5.0
現在の EventTarget を唯一のエントリーとして含む配列を返します。イベントがディスパッチされていない場合は空です。これはNode.jsでは使用されず、完全を期すためにのみ提供されています。
event.currentTarget
Added in: v14.5.0
- Type: <EventTarget> イベントをディスパッチしている
EventTarget。
event.target のエイリアス。
event.defaultPrevented
Added in: v14.5.0
- Type: <boolean>
cancelable が true であり、event.preventDefault() が呼び出された場合は true。
event.eventPhase
Added in: v14.5.0
- Type: <number> イベントがディスパッチされていない間は
0を返し、ディスパッチされている間は2を返します。
これはNode.jsでは使用されず、完全を期すためにのみ提供されています。
event.initEvent(type[, bubbles[, cancelable]])
Added in: v19.5.0
[Stable: 3 - Legacy]
Stable: 3 Stability: 3 - レガシー: WHATWG仕様では非推奨とされており、ユーザーはまったく使用すべきではありません。
イベントコンストラクターと冗長であり、composed を設定できません。これはNode.jsでは使用されず、完全を期すためにのみ提供されています。
event.isTrusted
Added in: v14.5.0
- Type: <boolean>
<AbortSignal> "abort" イベントは、isTrusted が true に設定されて発行されます。それ以外の場合は false です。
event.preventDefault()
Added in: v14.5.0
cancelable が true の場合、defaultPrevented プロパティを true に設定します。
event.returnValue
Added in: v14.5.0
[Stable: 3 - Legacy]
Stable: 3 Stability: 3 - Legacy: 代わりに event.defaultPrevented を使用してください。
- Type: <boolean> イベントがキャンセルされていない場合は true。
event.returnValue の値は常に event.defaultPrevented の反対です。 これは Node.js では使用されず、完全に網羅するために提供されています。
event.srcElement
Added in: v14.5.0
[Stable: 3 - Legacy]
Stable: 3 Stability: 3 - Legacy: 代わりに event.target を使用してください。
- Type: <EventTarget> イベントをディスパッチする
EventTarget。
event.target のエイリアス。
event.stopImmediatePropagation()
Added in: v14.5.0
現在のイベントリスナーが完了した後、イベントリスナーの呼び出しを停止します。
event.stopPropagation()
Added in: v14.5.0
これは Node.js では使用されず、完全に網羅するために提供されています。
event.target
Added in: v14.5.0
- Type: <EventTarget> イベントをディスパッチする
EventTarget。
event.timeStamp
Added in: v14.5.0
- Type: <number>
Event オブジェクトが作成されたときのミリ秒単位のタイムスタンプ。
event.type
Added in: v14.5.0
- Type: <string>
イベントタイプ識別子。
Class: EventTarget
[History]
| Version | Changes |
|---|---|
| v15.0.0 | EventTarget クラスがグローバルオブジェクトから利用可能になりました。 |
| v14.5.0 | Added in: v14.5.0 |
eventTarget.addEventListener(type, listener[, options])
[History]
| Version | Changes |
|---|---|
| v15.4.0 | signal オプションのサポートを追加。 |
| v14.5.0 | Added in: v14.5.0 |
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)
Added in: v14.5.0
event<Event>- 戻り値: <boolean> event の
cancelable属性値が false であるか、またはpreventDefault()メソッドが呼び出されなかった場合はtrue。それ以外の場合はfalse。
event.type のハンドラーのリストに event をディスパッチします。
登録されたイベントリスナーは、登録された順に同期的に呼び出されます。
eventTarget.removeEventListener(type, listener[, options])
Added in: v14.5.0
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
イベント type のハンドラーのリストから listener を削除します。
Class: CustomEvent
[History]
| Version | Changes |
|---|---|
| v23.0.0 | No longer experimental. |
| v22.1.0, v20.13.0 | CustomEvent is now stable. |
| v19.0.0 | No longer behind --experimental-global-customevent CLI flag. |
| v18.7.0, v16.17.0 | Added in: v18.7.0, v16.17.0 |
- 拡張: <Event>
CustomEvent オブジェクトは、CustomEvent Web API のアダプテーションです。インスタンスは Node.js によって内部的に作成されます。
event.detail
[History]
| Version | Changes |
|---|---|
| v22.1.0, v20.13.0 | CustomEvent is now stable. |
| v18.7.0, v16.17.0 | Added in: v18.7.0, v16.17.0 |
- タイプ: <any> 初期化時に渡されるカスタムデータを返します。
読み取り専用。
クラス: NodeEventTarget
追加: v14.5.0
- 拡張: <EventTarget>
NodeEventTarget は、EventEmitter API のサブセットをエミュレートする Node.js 固有の EventTarget の拡張です。
nodeEventTarget.addListener(type, listener)
追加: v14.5.0
type<string>listener<Function> | <EventListener>- 戻り値: <EventTarget>
this
EventEmitter API と同等のものをエミュレートする、EventTarget クラスの Node.js 固有の拡張。 addListener() と addEventListener() の唯一の違いは、addListener() が EventTarget への参照を返すことです。
nodeEventTarget.emit(type, arg)
追加: v15.2.0
EventTarget クラスの Node.js 固有の拡張で、type のハンドラーのリストに arg をディスパッチします。
nodeEventTarget.eventNames()
追加: v14.5.0
- 戻り値: <string[]>
イベントリスナーが登録されているイベントの type 名の配列を返す、EventTarget クラスの Node.js 固有の拡張。
nodeEventTarget.listenerCount(type)
追加: v14.5.0
type に登録されているイベントリスナーの数を返す、EventTarget クラスの Node.js 固有の拡張。
nodeEventTarget.setMaxListeners(n)
Added in: v14.5.0
n<number>
Node.js固有のEventTargetクラスの拡張で、最大イベントリスナー数をnとして設定します。
nodeEventTarget.getMaxListeners()
Added in: v14.5.0
- 戻り値: <number>
Node.js固有のEventTargetクラスの拡張で、最大イベントリスナー数を返します。
nodeEventTarget.off(type, listener[, options])
Added in: v14.5.0
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
戻り値: <EventTarget> this
Node.js固有のeventTarget.removeEventListener()のエイリアスです。
nodeEventTarget.on(type, listener)
Added in: v14.5.0
type<string>listener<Function> | <EventListener>- 戻り値: <EventTarget> this
Node.js固有のeventTarget.addEventListener()のエイリアスです。
nodeEventTarget.once(type, listener)
Added in: v14.5.0
type<string>listener<Function> | <EventListener>- 戻り値: <EventTarget> this
Node.js固有のEventTargetクラスの拡張で、指定されたイベントtypeに対してonceリスナーを追加します。これは、onceオプションをtrueに設定してonを呼び出すことと同等です。
nodeEventTarget.removeAllListeners([type])
Added in: v14.5.0
type<string>- 返します: <EventTarget> this
Node.js 固有の EventTarget クラスの拡張です。type が指定された場合、type に登録されているすべてのリスナーを削除します。それ以外の場合は、登録されているすべてのリスナーを削除します。
nodeEventTarget.removeListener(type, listener[, options])
Added in: v14.5.0
type<string>listener<Function> | <EventListener>options<Object>capture<boolean>
返します: <EventTarget> this
Node.js 固有の EventTarget クラスの拡張で、指定された type の listener を削除します。removeListener() と removeEventListener() の唯一の違いは、removeListener() が EventTarget への参照を返すことです。