イベント#

安定性: 2 - 安定

ソースコード: 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: 2const EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
// Prints: 1
myEmitter.emit('event');
// Prints: 2

eventEmitter.once() メソッドを使用すると、特定のイベントに対して最大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');
// 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!'));
// Throws and crashes Node.jsconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// Throws and crashes Node.js

Node.js プロセスのクラッシュを防ぐために、domain モジュールを使用できます。(ただし、`node:domain` モジュールは非推奨です。)

ベストプラクティスとして、`'error'` イベントのリスナーは常に追加する必要があります。

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

シンボル `events.errorMonitor` を使用してリスナーをインストールすることにより、発行されたエラーを使用せずに `'error'` イベントを監視できます。

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

const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
  MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Still throws and crashes Node.jsconst { EventEmitter, errorMonitor } = require('node:events');

const myEmitter = new EventEmitter();
myEmitter.on(errorMonitor, (err) => {
  MyMonitoringTool.log(err);
});
myEmitter.emit('error', new Error('whoops!'));
// Still throws and crashes Node.js

Promise の拒否をキャプチャする#

イベントハンドラで `async` 関数を使用すると、例外がスローされた場合に未処理の拒否が発生する可能性があるため、問題が発生します。

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

EventEmitter コンストラクタの `captureRejections` オプション、またはグローバル設定は、この動作を変更し、`Promise` に `.then(undefined, handler)` ハンドラをインストールします。このハンドラは、例外を非同期的に Symbol.for('nodejs.rejection') メソッド(存在する場合)または 'error' イベントハンドラ(存在しない場合)にルーティングします。

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

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

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

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

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

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

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

`events.captureRejections = true` を設定すると、`EventEmitter` のすべての新しいインスタンスのデフォルトが変更されます。

import { EventEmitter } from 'node:events';

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

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

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

`captureRejections` 動作によって生成される `'error'` イベントには、無限エラーループを回避するための catch ハンドラがありません。推奨事項は、**`async` 関数を `'error'` イベントハンドラとして使用しない**ことです。

クラス: EventEmitter#

EventEmitter クラスは、`node:events` モジュールによって定義および公開されます。

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

すべての `EventEmitter` は、新しいリスナーが追加されたときに `'newListener'` イベントを、既存のリスナーが削除されたときに `'removeListener'` イベントを発行します。

以下のオプションをサポートしています。

イベント: 'newListener'#

EventEmitter インスタンスは、リスナーが内部リスナー配列に追加される*前*に、独自の `'newListener'` イベントを発行します。

`'newListener'` イベントに登録されたリスナーには、イベント名と、追加されるリスナーへの参照が渡されます。

イベントがリスナーの追加前にトリガーされるという事実は、微妙ですが重要な副作用があります。`'newListener'` コールバック*内*で同じ `name` に登録された*追加の*リスナーは、追加中のリスナーの*前*に挿入されます。

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

const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Insert a new listener in front
    myEmitter.on('event', () => {
      console.log('B');
    });
  }
});
myEmitter.on('event', () => {
  console.log('A');
});
myEmitter.emit('event');
// Prints:
//   B
//   Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Insert a new listener in front
    myEmitter.on('event', () => {
      console.log('B');
    });
  }
});
myEmitter.on('event', () => {
  console.log('A');
});
myEmitter.emit('event');
// Prints:
//   B
//   A

イベント: 'removeListener'#

  • eventName <string> | <symbol> イベント名
  • listener <Function> イベントハンドラ関数

'removeListener' イベントは、listener が削除された*後*に発行されます。

emitter.addListener(eventName, listener)#

  • eventName <string> | <symbol>
  • listener <Function>

emitter.on(eventName, listener) のエイリアスです。

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

  • eventName <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 listenerconst EventEmitter = require('node:events');
const myEmitter = new EventEmitter();

// First listener
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ');
  console.log(`event with parameters ${parameters} in third listener`);
});

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

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

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

emitter.eventNames()#

  • 戻り値: <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 が既に追加されているかどうかを確認するチェックは行われません。 eventNamelistener の同じ組み合わせを渡す複数の呼び出しを行うと、listener が複数回追加され、呼び出されます。

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

EventEmitter への参照を返すため、呼び出しをチェーンできます。

デフォルトでは、イベントリスナーは追加された順序で呼び出されます。 emitter.prependListener() メソッドを代わりに使用して、イベントリスナーをリスナー配列の先頭に追加できます。

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

emitter.once(eventName, listener)#

  • eventName <string> | <symbol> イベントの名前。
  • listener <Function> コールバック関数
  • 戻り値: <EventEmitter>

eventName という名前のイベントの**ワンタイム** listener 関数を追加します。次回 eventName がトリガーされると、このリスナーは削除されてから呼び出されます。

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

EventEmitter への参照を返すため、呼び出しをチェーンできます。

デフォルトでは、イベントリスナーは追加された順序で呼び出されます。 emitter.prependOnceListener() メソッドを代わりに使用して、イベントリスナーをリスナー配列の先頭に追加できます。

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

emitter.prependListener(eventName, listener)#

  • eventName <string> | <symbol> イベントの名前。
  • listener <Function> コールバック関数
  • 戻り値: <EventEmitter>

eventName という名前のイベントのリスナー配列の*先頭*に listener 関数を追加します。 listener が既に追加されているかどうかを確認するチェックは行われません。 eventNamelistener の同じ組み合わせを渡す複数の呼び出しを行うと、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:
//   Aconst EventEmitter = require('node:events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();

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

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

myEmitter.on('event', callbackA);

myEmitter.on('event', callbackB);

// callbackA removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
//   A
//   B

// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
//   A

リスナーは内部配列を使用して管理されるため、これを呼び出すと、削除されるリスナーの*後*に登録されたリスナーの位置インデックスが変更されます。これは、リスナーが呼び出される順序には影響しませんが、emitter.listeners() メソッドによって返されるリスナー配列のコピーを再作成する必要があることを意味します。

単一の関数が単一のイベントのハンドラーとして複数回追加されている場合(以下の例のように)、removeListener() は最も最近追加されたインスタンスを削除します。この例では、once('ping') リスナーが削除されます。

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

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

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

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

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

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

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

EventEmitter への参照を返すため、呼び出しをチェーンできます。

emitter.setMaxListeners(n)#

  • n <integer>
  • 戻り値: <EventEmitter>

デフォルトでは、特定のイベントに 10 を超えるリスナーが追加されると、EventEmitter は警告を出力します。これは、メモリリークを見つけるのに役立つ便利なデフォルトです。 emitter.setMaxListeners() メソッドを使用すると、この特定の EventEmitter インスタンスの制限を変更できます。値を Infinity(または 0)に設定して、リスナーの数を無制限にすることができます。

EventEmitter への参照を返すため、呼び出しをチェーンできます。

emitter.rawListeners(eventName)#

  • eventName <string> | <symbol>
  • 戻り値: <Function[]>

eventName という名前のイベントのリスナー配列のコピーを、ラッパー(.once() によって作成されたラッパーなど)を含めて返します。

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

// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];

// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();

// Logs "log once" to the console and removes the listener
logFnWrapper();

emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');

// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');const EventEmitter = require('node:events');
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));

// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];

// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();

// Logs "log once" to the console and removes the listener
logFnWrapper();

emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');

// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');

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

  • 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') で検査でき、イベントエミッターインスタンス、イベントの名前、およびアタッチされたリスナーの数をそれぞれ参照する追加の emittertype、および count プロパティがあります。その name プロパティは 'MaxListenersExceededWarning' に設定されています。

events.errorMonitor#

このシンボルは、'error' イベントのみを監視するリスナーをインストールするために使用されます。このシンボルを使用してインストールされたリスナーは、通常の 'error' リスナーが呼び出される*前*に呼び出されます。

このシンボルを使用してリスナーをインストールしても、'error' イベントが発行された後の動作は変更されません。そのため、通常の 'error' リスナーがインストールされていない場合、プロセスは引き続きクラッシュします。

events.getEventListeners(emitterOrTarget, eventName)#

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)#

現在設定されているリスナーの最大数を返します。

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])#

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 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(); // 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)#

安定性: 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: 2

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

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

const ee = new EventEmitter();

// Emit later on
process.nextTick(() => {
  ee.emit('foo', 'bar');
  ee.emit('foo', 42);
});

for await (const event of on(ee, 'foo')) {
  // The execution of this inner block is synchronous and it
  // processes one event at a time (even with await). Do not use
  // if concurrent execution is required.
  console.log(event); // prints ['bar'] [42]
}
// Unreachable hereconst { on, EventEmitter } = require('node:events');

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

  // Emit later on
  process.nextTick(() => {
    ee.emit('foo', 'bar');
    ee.emit('foo', 42);
  });

  for await (const event of on(ee, 'foo')) {
    // The execution of this inner block is synchronous and it
    // processes one event at a time (even with await). Do not use
    // if concurrent execution is required.
    console.log(event); // prints ['bar'] [42]
  }
  // Unreachable here
})();

eventName イベントを反復処理する AsyncIterator を返します。EventEmitter'error' を発行すると、例外がスローされます。ループを終了すると、すべてのリスナーが削除されます。各反復によって返される value は、発行されたイベント引数で構成される配列です。

<AbortSignal> を使用して、イベントの待機をキャンセルできます。

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

const ac = new AbortController();

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

  // Emit later on
  process.nextTick(() => {
    ee.emit('foo', 'bar');
    ee.emit('foo', 42);
  });

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // The execution of this inner block is synchronous and it
    // processes one event at a time (even with await). Do not use
    // if concurrent execution is required.
    console.log(event); // prints ['bar'] [42]
  }
  // Unreachable here
})();

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

const ac = new AbortController();

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

  // Emit later on
  process.nextTick(() => {
    ee.emit('foo', 'bar');
    ee.emit('foo', 42);
  });

  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
    // The execution of this inner block is synchronous and it
    // processes one event at a time (even with await). Do not use
    // if concurrent execution is required.
    console.log(event); // prints ['bar'] [42]
  }
  // Unreachable here
})();

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

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

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)#

安定性: 1 - 実験的

指定された signalabort イベントを一度だけリッスンします。

中止シグナルの `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 オブジェクトには、この 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 の EventTargetEventTarget Web API には、2 つの重要な違いがあります。

  1. DOM の EventTarget インスタンスは階層的である場合がありますが、Node.js には階層とイベント伝播の概念はありません。つまり、EventTarget にディスパッチされたイベントは、それぞれ独自のイベントハンドラセットを持つ可能性のあるネストされたターゲットオブジェクトの階層を伝播しません。
  2. Node.js の EventTarget では、イベントリスナーが async 関数であるか Promise を返す場合、返された Promise が拒否されると、拒否は自動的に捕捉され、同期的にスローするリスナーと同じ方法で処理されます(詳細は EventTarget エラー処理 を参照)。

NodeEventTargetEventEmitter の比較#

NodeEventTarget オブジェクトは、特定の状況で EventEmitter を厳密に *エミュレート* できるようにする、EventEmitter API の変更されたサブセットを実装します。 NodeEventTargetEventEmitter のインスタンスではなく、ほとんどの場合、EventEmitter の代わりに使用することはできません。

  1. EventEmitter とは異なり、任意の listener はイベント type ごとに最大 1 回だけ登録できます。 listener を複数回登録しようとすると無視されます。
  2. NodeEventTarget は、完全な EventEmitter API をエミュレートしません。具体的には、prependListener()prependOnceListener()rawListeners()、および errorMonitor API はエミュレートされません。 'newListener' イベントと 'removeListener' イベントも発行されません。
  3. NodeEventTarget は、タイプ 'error' のイベントに対して特別なデフォルトの動作を実装しません。
  4. 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#

安定性: 3 - レガシー: WHATWG 仕様では非推奨と見なされており、ユーザーはまったく使用しないでください。代わりに event.stopPropagation() を使用してください。

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#

cancelabletrue で、event.preventDefault() が呼び出されている場合は true です。

event.eventPhase#
  • タイプ: <number> イベントがディスパッチされていない間は 0 を返し、ディスパッチされている間は 2 を返します。

これは Node.js では使用されず、完全性のためにのみ提供されています。

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

安定性: 3 - レガシー: WHATWG 仕様では非推奨と見なされており、ユーザーはまったく使用しないでください。

イベントコンストラクタと冗長であり、composed を設定できません。これは Node.js では使用されず、完全性のためにのみ提供されています。

event.isTrusted#

<AbortSignal> "abort" イベントは、isTrustedtrue に設定されて発行されます。その他のすべての場合、値は false です。

event.preventDefault()#

cancelabletrue の場合、defaultPrevented プロパティを true に設定します。

event.returnValue#

安定性: 3 - レガシー: 代わりに event.defaultPrevented を使用してください。

  • タイプ: <boolean> イベントがキャンセルされていない場合は true です。

event.returnValue の値は、常に event.defaultPrevented の反対です。これは Node.js では使用されず、完全性のためにのみ提供されています。

event.srcElement#

安定性: 3 - レガシー: 代わりに event.target を使用してください。

  • タイプ: <EventTarget> イベントをディスパッチする EventTarget です。

event.target のエイリアスです。

event.stopImmediatePropagation()#

現在のイベントリスナーが完了した後、イベントリスナーの呼び出しを停止します。

event.stopPropagation()#

これは Node.js では使用されず、完全性のためにのみ提供されています。

event.target#
  • タイプ: <EventTarget> イベントをディスパッチする EventTarget です。
event.timeStamp#

Event オブジェクトが作成されたミリ秒単位のタイムスタンプです。

event.type#

イベントタイプ識別子です。

クラス: 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

eventevent.type のハンドラーリストにディスパッチします。

登録されたイベントリスナーは、登録された順序で同期的に呼び出されます。

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

イベント type のハンドラーリストから listener を削除します。

クラス: CustomEvent#

安定性: 1 - 実験的。

CustomEvent オブジェクトは、CustomEvent Web API を Node.js向けに適用したものです。インスタンスは Node.js によって内部的に作成されます。

event.detail#

安定性: 1 - 実験的。

  • 型: <any> 初期化時に渡されたカスタムデータを返します。

読み取り専用。

クラス: NodeEventTarget#

NodeEventTarget は、EventEmitter API のサブセットをエミュレートする、Node.js 独自の EventTarget 拡張です。

nodeEventTarget.addListener(type, listener)#

EventEmitter API と同等の機能をエミュレートする、Node.js 独自の EventTarget クラス拡張です。 addListener()addEventListener() の唯一の違いは、addListener()EventTarget への参照を返すことです。

nodeEventTarget.emit(type, arg)#
  • type <string>
  • arg <any>
  • 戻り値: <boolean> type に登録されたイベントリスナーが存在する場合は true、そうでない場合は false

argtype のハンドラーリストにディスパッチする、Node.js 独自の EventTarget クラス拡張です。

nodeEventTarget.eventNames()#

イベントリスナーが登録されているイベント type 名の配列を返す、Node.js 独自の EventTarget クラス拡張です。

nodeEventTarget.listenerCount(type)#

type に登録されているイベントリスナーの数を返す、Node.js 独自の EventTarget クラス拡張です。

nodeEventTarget.setMaxListeners(n)#

最大イベントリスナー数を n に設定する、Node.js 独自の EventTarget クラス拡張です。

nodeEventTarget.getMaxListeners()#

最大イベントリスナーの数を返す、Node.js 独自の EventTarget クラス拡張です。

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

eventTarget.removeEventListener() の Node.js 独自のエイリアスです。

nodeEventTarget.on(type, listener)#

eventTarget.addEventListener() の Node.js 独自のエイリアスです。

nodeEventTarget.once(type, listener)#

指定されたイベント type に対して once リスナーを追加する、Node.js 独自の EventTarget クラス拡張です。これは、once オプションを true に設定して on を呼び出すことと同じです。

nodeEventTarget.removeAllListeners([type])#

Node.js 独自の EventTarget クラス拡張です。 type が指定されている場合、type のすべての登録済みリスナーを削除します。そうでない場合は、すべての登録済みリスナーを削除します。

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

指定された typelistener を削除する、Node.js 独自の EventTarget クラス拡張です。 removeListener()removeEventListener() の唯一の違いは、removeListener()EventTarget への参照を返すことです。