Node.js イベントエミッター


Node.js のすべての非同期 I/O 操作は、完了時にイベントをイベント キューに送信します。

Node.js の多くのオブジェクトはイベントを発行します。net.Server オブジェクトは新しい接続が確立されるたびにイベントを発行し、fs.readStream オブジェクトはファイルが開かれたときにイベントを発行します。 これらのイベント生成オブジェクトはすべて events.EventEmitter のインスタンスです。


EventEmitter クラス

events モジュールは、events.EventEmitter という 1 つのオブジェクトのみを提供します。 EventEmitter の中核は、イベント トリガー関数とイベント リスナー関数のカプセル化です。

このモジュールには、require("events"); を通じてアクセスできます。

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

EventEmitter オブジェクトは、インスタンス化中にエラーが発生した場合に「error」イベントをトリガーします。新しいリスナーが追加されると「newListener」イベントが発生し、リスナーが削除されると「removeListener」イベントが発生します。

以下では、簡単な例を使用して EventEmitter の使用法を説明します:

//event.js 文件
var EventEmitter = require('events').EventEmitter; 
var event = new EventEmitter(); 
event.on('some_event', function() { 
	console.log('some_event 事件触发'); 
}); 
setTimeout(function() { 
	event.emit('some_event'); 
}, 1000);

実行結果は次のとおりです:

このコードを実行すると、1 秒後にコンソールに 「some_event イベントがトリガーされました」 が出力されます。原則として、イベント オブジェクトがイベント some_event のリスナーを登録し、1000 ミリ秒後に setTimeout を使用してイベント オブジェクトにイベント some_event を送信します。このとき、some_event のリスナーが呼び出されます。

$ node event.js 
some_event 事件触发

EventEmitter の各イベントは、イベント名といくつかのパラメーターで構成されます。イベント名は通常、特定のセマンティクスを表す文字列です。イベントごとに、EventEmitter は複数のイベント リスナーをサポートします。

イベントがトリガーされると、このイベントに登録されているイベントリスナーが順番に呼び出され、イベントパラメータがコールバック関数のパラメータとして渡されます。

次の例でこのプロセスを説明しましょう:

//event.js 文件
var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.on('someEvent', function(arg1, arg2) { 
	console.log('listener1', arg1, arg2); 
}); 
emitter.on('someEvent', function(arg1, arg2) { 
	console.log('listener2', arg1, arg2); 
}); 
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');

上記のコードを実行すると、実行結果は次のようになります:

$ node event.js 
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数

上記の例では、エミッターはイベント someEvent に対して 2 つのイベント リスナーを登録し、トリガーしました。 someEvent イベント。

実行結果では、2 つのイベント リスナー コールバック関数が連続して呼び出されていることがわかります。 これは EventEmitter の最も単純な使用法です。

EventEmitter は、onemit などの複数のプロパティを提供します。 on 関数はイベント関数をバインドするために使用され、emit 属性はイベントをトリガーするために使用されます。次に、EventEmitter のプロパティを詳しく見てみましょう。

メソッド

8
シリアル番号メソッドと説明
1addListener(event,listener)
指定されたイベントのリスナーをリスナー配列の末尾に追加します。
2on(event,listener)
文字列イベントとコールバック関数を受け入れて、指定されたイベントのリスナーを登録します。
server.on('connection', function (stream) {
  console.log('someone connected!');
});
3once(event,listener)
指定されたイベントのワンタイムリスナーを登録します。つまり、リスナーは最大でも 1 回だけトリガーされ、リスナーはトリガー直後に解放されます。 。
server.once('connection', function (stream) {
  console.log('Ah, we have our first user!');
});
4removeListener(event,listener)
指定されたイベントのリスナーを削除します。リスナーは、イベントに登録されたリスナーである必要があります。
var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
5removeAllListeners([event])
すべてのイベントのすべてのリスナーを削除します。イベントが指定されている場合は、指定されたイベントのすべてのリスナーを削除します。
6setMaxListeners(n)
デフォルトでは、10 を超えるリスナーを追加すると、EventEmitters は警告メッセージを出力します。 setMaxListeners 関数は、リスナー数のデフォルト制限を増やすために使用されます。
7listeners(event)
指定されたイベントのリスナー配列を返します。
emit(event, [arg1], [arg2], [...]) イベントに登録されたリスナーがある場合は true を返し、そうでない場合はパラメータの順序で各リスナーを実行します。 false を返します。
クラスメソッド

シリアル番号メソッドと説明1
listenerCount(emitter,event)指定されたイベントのリスナーの数を返します。イベント名
listener

- イベントを処理します 機能

このイベントは、新しいリスナーが追加されたときにトリガーされます。 2removeListener

次の例は、接続イベントを介した EventEmitter クラスのアプリケーションを示しています。

main.js ファイルを作成します。コードは次のとおりです。

var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listener1 = function listener1() {
   console.log('监听器 listener1 执行。');
}

// 监听器 #2
var listener2 = function listener2() {
  console.log('监听器 listener2 执行。');
}

// 绑定 connection 事件,处理函数为 listener1 
eventEmitter.addListener('connection', listener1);

// 绑定 connection 事件,处理函数为 listener2
eventEmitter.on('connection', listener2);

var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。");

// 处理 connection 事件 
eventEmitter.emit('connection');

// 移除监绑定的 listener1 函数
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受监听。");

// 触发连接事件
eventEmitter.emit('connection');

eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。");

console.log("程序执行完毕。");

上記のコード、実行結果は次のとおりです。

$ node main.js
2 个监听器监听连接事件。
监听器 listener1 执行。
监听器 listener2 执行。
listener1 不再受监听。
监听器 listener2 执行。
1 个监听器监听连接事件。
程序执行完毕。

error events

EventEmitter は、特殊なイベント エラーを定義します。エラーに遭遇したとき。 エラー イベントは通常、例外が発生したときにトリガーされます。

エラーがトリガーされたとき、応答がない場合は EventEmitter が規定します 対応するリスナーが使用されている場合、Node.js はそれを例外として扱い、プログラムを終了し、エラー メッセージを出力します。

通常、エラーのトリガーについて心配する必要があります エラーが発生したときにプログラム全体がクラッシュするのを避けるために、イベント オブジェクトにリスナーを設定します。例:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.emit('error');

実行時に次のエラーが表示されます:

node.js:201 
throw e; // process.nextTick error, or 'error' event on first tick 
^ 
Error: Uncaught, unspecified 'error' event. 
at EventEmitter.emit (events.js:50:15) 
at Object.<anonymous> (/home/byvoid/error.js:5:9) 
at Module._compile (module.js:441:26) 
at Object..js (module.js:459:10) 
at Module.load (module.js:348:31) 
at Function._load (module.js:308:12) 
at Array.0 (module.js:479:10) 
at EventEmitter._tickCallback (node.js:192:40)

EventEmitter の継承

ほとんどの場合、EventEmitter を直接使用することはなく、オブジェクト内で継承します。 fs、ネットを含む イベント応答をサポートするコア モジュールが EventEmitter のサブクラスである限り、http を含みます。

なぜこんなことをするのですか?理由は 2 つあります:

まず第一に、特定のエンティティ関数を持つオブジェクトのイベント実装はセマンティクスに準拠しています。 イベントのリスニングと発行はオブジェクトのメソッドである必要があります。

第二に、JavaScript のオブジェクト メカニズムはプロトタイプとサポートに基づいています。 部分的な多重継承では、EventEmitter を継承しても、オブジェクトの元の継承関係が崩れることはありません。


  • event

    - 文字列、イベント名

  • listener

    - イベント関数

  • を処理します指定されたリスナー配列からリスナーを削除します。この操作により、削除されたリスナーの後にそれらのリスナーのインデックスが変更されることに注意してください。