2013年2月22日 星期五

Node.js EventEmitter 事件管理神器

Standard
如果你已經相當熟悉 JavaScript 的開發,那就肯定對其事件機制不陌生。我們等待一個物件產生事件,去觸發我們設定的 callback 函式,是最常見不過的東西了。不過,如果你想要設計一個自己的物件,並容許別人可以監聽它的事件,要怎麼做呢?

如果你什麼都沒有,你肯定是在自己的物件中宣告一個 event handler 的表,當別人想要針對特定的事件掛上 callback function 時,就記錄在該表內。然後在事件被產生時,去呼較對應事件的所有 callback function。然後,你會設計像 .on() 、off() 和 emit() 之類的方法,讓別人可以使用。

是的,很累。既然事件機制是我們在 JavaScript 中常用的功能,每個物件都寫一次這樣簡單的事件管理,真的很浪費時間。其實,Node.js 本來就有實作這樣的機制『EventEmitter』讓開發者直接使用。

EventEmitter 的使用方法很簡單:
var util = require('util');
var events = require('events');

var MyClass = function() {
};

util.inherits(MyClass, events.EventEmitter);

MyClass.prototype.ping = function() {
    this.emit('response', 'pong');
};

實際使用這個 Class 建立物件,然後監聽事件,最後觸發事件:
var myClass = new MyClass();

myClass.on('response', function(msg) {
    console.log(msg);
});

myClass.ping();

後記

把 EventEmitter 的繼承寫在 Class 宣告和 prototype 宣告之間很彆扭,但在 Class 宣告後立即使其繼承 EventEmitter 是正確的邏輯行為,所以,勉強接受他吧。