Tatsuya Oiwa About Archive Feed Github Twitter

Node.jsのEventsとEventEmitter

Node.jsのEventsモジュールを使って、独自のイベントを作成することができる。

例えば、あるボタンが押されたときにLEDのランプを点滅させたいとき、以下のように実装する。

var events = require('events');

var eventEmitter = new events.EventEmitter();

var blink = function() {
  console.log('blinking');
}

eventEmitter.on('pressButton', blink);

eventEmitter.emit('pressButton');

まず、require('events')でEventsモジュールを読み込み、EventEmitterクラスのインスタンスを作成する。次に、blink()という関数内で、LEDランプを点滅させるコードを書き(実際には'blinking'という文字列を表示するだけ)、イベントが発生したらこの関数が呼ばれるようにする。

そして、先ほど作成したEventEmitterのインスタンスのon()関数で、第一引数にイベント名となる文字列pressButton、第二引数に、そのイベントが発生した時に呼ばれる関数blink()を渡す。

最後に、eventEmitter.emit()関数を実行すると、先ほどリスナーとして登録した関数が呼ばれる。

また、一つのイベントに対して複数のリスナーを登録することもできる。

var events = require('events');

var eventEmitter = new events.EventEmitter();

var blinkOne = function() {
  console.log('blinking one');
}
var blinkTwo = function() {
  console.log('blinking two');
}
var blinkThree = function() {
  console.log('blinking three');
}

eventEmitter.on('pressButton', blinkOne);
eventEmitter.on('pressButton', blinkTwo);
eventEmitter.on('pressButton', blinkThree);

eventEmitter.emit('pressButton');

さらに、リスナーの関数に対して引数を渡したい場合は、emit()関数の第二引数以降に値を渡すことができる。

var events = require('events');

var eventEmitter = new events.EventEmitter();

var blink = function(led) {
  console.log('blinking ' + led);
}

eventEmitter.on('pressButton', blink);

eventEmitter.emit('pressButton', 'one');

なお、EventEmitterを使った別の手法として、EventEmitterクラスを継承する方法がある。

LEDランプのプログラムをこの方法に書き換えるために、新たにButtonという名前のクラスを作成し、press()という関数からpressButtonイベントを呼べるようにする。

var events = require('events');
var util = require('util');

function Button(led) {
  this.led = led;
  events.EventEmitter.call(this);
}

util.inherits(Button, events.EventEmitter);

Button.prototype.press = function() {
  this.emit('press', this.led);
}

var blink = function(led) {
  console.log('blinking ' + led);
}

var buttonOne = new Button('one');
buttonOne.on('press', blink);
buttonOne.press();

Buttonオブジェクトのコンストラクタは、LEDランプの名前ledを引数にとり、さらにcall()関数でEventEmitterオブジェクトのコンストラクタを実行する。そして、Node.jsのutilモジュールのinherits()関数を使って、EventEmitterのプロパティをButtonオブジェクトにコピーする。すると、ButtonクラスのインスタンスからEventEmitteron()emit()などの関数を実行することができるようになる。

最後に、登録したリスナーはremoveListener()で削除することができる。

buttonOne.removeListener('press', blink);

その他のAPIについては、公式ドキュメントを参照。