EventEmitter
を拡張し、finish
というイベントをリッスンする2つのオブジェクトのインスタンスがあります。イベントハンドラをコンストラクタの外に設定すると、すべてが期待通りに機能します。各インスタンスは、それがトリガーする、finish
の出現を聞きます。しかし、イベントハンドラをコンストラクタ内に設定すると、作成されたインスタンスだけがイベントを聞いて反応します。ここでコンストラクタ内のイベントハンドラは、コンストラクタ外のイベントハンドラとは異なる動作をします
コードは次のとおりです。MyEmitter
のコンストラクタ内に設置されているイベントハンドラのバージョンにLISTENER ID
は常にそれがそのインスタンスように見える作り、二作成したインスタンスに属していることを
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var NEXT_ID = 0;
var MyEmitter = function() {
EventEmitter.call(this);
this.id = NEXT_ID;
NEXT_ID++;
console.log('CREATED EMITTER WITH ID:', this.id)
self = this;
this.on('finish', function() {
console.log('FINISH EVENT . CONSTRUCTOR LISTENER .',
'LISTENER ID:', self.id,
'. ORIGINATOR ID:', this.id);
});
};
util.inherits(MyEmitter, EventEmitter);
var setFinishListener = function(emitter) {
emitter.on('finish', function() {
console.log('FINISH EVENT . NON-CONSTRUCTOR LISTENER .',
'LISTENER ID:', emitter.id,
'. ORIGINATOR ID:', this.id);
});
}
var emitter0 = new MyEmitter();
var emitter1 = new MyEmitter();
setFinishListener(emitter0);
setFinishListener(emitter1);
emitter0.emit('finish');
emitter1.emit('finish');
// The following is logged to the console:
// FINISH EVENT . CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 0
// FINISH EVENT . NON-CONSTRUCTOR LISTENER . LISTENER ID: 0 . ORIGINATOR ID: 0
// FINISH EVENT . CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 1
// FINISH EVENT . NON-CONSTRUCTOR LISTENER . LISTENER ID: 1 . ORIGINATOR ID: 1
をお知らせ何らかの理由で最初に作成されたインスタンスにそのハンドラがトリガされることはありません。私は私が正しく理解と仮定しています
二つの事実:
this
イベントハンドラでは、常にイベントを発行したオブジェクトである必要があります。this
はコンストラクタで常に返されるオブジェクトである必要があります(new
で呼び出されるため)。
これらの両方が真である場合は、私が他の何かを理解していないとわかりません。
もう1つこれについて私は考えました:イベントは、イベントを発行したのと同じEventEmitterによって常に「聞かれる」べきですか?それは私が思ったことであり、確かにそれが最も一般的な使用事例であるようです。しかし、それが制限ではない場合、たとえば、ボタン上のclick
イベントは、他のすべてのボタンのクリックハンドラをトリガしません。
私がそれを見逃していたことがどれほどばかげているのか信じられません。誰かの古いコードでこれを修正しようとしていて、あまりにも深く見えていました。自己の前にvarの不足を完全に逃した。ありがとう! – spectorar