揭秘Node.js事件
要使用NodeJS,你需要知道一個重要的東西:事件(events)。Node中有很多對象都可以觸發事件,Node的文檔中有很多示例。但文檔也許并不能清晰的講解如何編寫自定義事件以及監聽函數。對于一些簡單的程序你可以不使用自定義事件,但這樣很難應對復雜的應用。那么如何編寫自定義事件?首先需要了解的是在node.js中的’events’模塊。
快速概覽
要訪問此模塊,只需使用如下語句:
require(‘events’)
requires(‘events’).EventEmitter
特別說明,node中所有能觸發事件的對象基本上都是后者的實例。讓我們創建一個簡單的演示程序Dummy:
dummy.js
- // basic imports
- var events = require('events');
- // for us to do a require later
- module.exports = Dummy;
- function Dummy() {
- events.EventEmitter.call(this);
- }
- // inherit events.EventEmitter
- Dummy.super_ = events.EventEmitter;
- Dummy.prototype = Object.create(events.EventEmitter.prototype, {
- constructor: {
- value: Dummy,
- enumerable: false
- }
- });
上述代碼中重點展示如何使用EventEmitter擴充對象,并從中繼承所有的原型對象,方法…等等。
現在,我們假設Dummy有一個cooking()的方法,一旦把食物做熟之后它會觸發’cooked’事件,并調用一個名為’eat’的回調函數。
dummy-cooking.js
- Dummy.prototype.cooking = function(chicken) {
- var self = this;
- self.chicken = chicken;
- self.cook = cook(); // assume dummy function that'll do the cooking
- self.cook(chicken, function(cooked_chicken) {
- self.chicken = cooked_chicken;
- self.emit('cooked', self.chicken);
- });
- return self;
- }
現在,這個模塊已經完成了。我們可以在主程序中使用它。
dummy-node.js
- // A nonsensical node.js program
- var Dummy = require('./dummy');
- var kenny = new Dummy();
- var dinner = kenny.cooking(fried_chix);
- dinner.on('cooked', function(chicken) {
- // eat up!
- }>
所以基本上,node.js執行腳本,然后等待’cooked’事件被觸發,并在事件觸發之后調用回調函數并傳遞返回的參數。
還有什么要注意的
值得注意的是,例子中使用的“子類”和事件有一些極端(a bit of an overkill)。EventEmitter每次只觸發一個事件(EventEmitter for things that only fire one event once)。如果只創造少數幾個實例,可以將方法直接加入到實例本身,如果要觸發底層事件,可能實用異步函數會更好一些。
關于events.EventEmitter,你還需注意一個特別的事件:’error’。任何錯誤發生時此事件都會觸發,并且當沒有監聽程序監聽這個事件時,node將會拋出異常并結束應用程序。(感謝Tim指出這一點)
結束之前的話
這篇文章簡要介紹了一些好的方法(good runthrough)。在發表之前文章之前,我查閱了我最喜愛的圖書館,參考別人的實現,并且還得到了別人的幫助弄把一些問題搞清楚。為了更好的理解node,我建議你閱讀Time Caswell的文章:
What is “this”? http://howtonode.org/what-is-this
同時,你也可以看一下我用node.js寫的機器人混搭應用(bot mashup)tocho,它使用了ircbot、logger、real-time websockets技術并支持搜索,但是處于開發的前期還比較粗糙。編寫這個程序給我帶來了很多樂趣。我還沒有將搜索功能發布到演示網站,您以使用支持web socket的瀏覽器訪問實時聊天室#node.js。
原文:http://www.grati.org/?p=318
【編輯推薦】