揭秘Node.js事件
要使用NodeJS,你需要知道一個(gè)重要的東西:事件(events)。Node中有很多對(duì)象都可以觸發(fā)事件,Node的文檔中有很多示例。但文檔也許并不能清晰的講解如何編寫自定義事件以及監(jiān)聽函數(shù)。對(duì)于一些簡單的程序你可以不使用自定義事件,但這樣很難應(yīng)對(duì)復(fù)雜的應(yīng)用。那么如何編寫自定義事件?首先需要了解的是在node.js中的’events’模塊。
快速概覽
要訪問此模塊,只需使用如下語句:
require(‘events’)
requires(‘events’).EventEmitter
特別說明,node中所有能觸發(fā)事件的對(duì)象基本上都是后者的實(shí)例。讓我們創(chuàng)建一個(gè)簡單的演示程序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
- }
- });
上述代碼中重點(diǎn)展示如何使用EventEmitter擴(kuò)充對(duì)象,并從中繼承所有的原型對(duì)象,方法…等等。
現(xiàn)在,我們假設(shè)Dummy有一個(gè)cooking()的方法,一旦把食物做熟之后它會(huì)觸發(fā)’cooked’事件,并調(diào)用一個(gè)名為’eat’的回調(diào)函數(shù)。
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;
- }
現(xiàn)在,這個(gè)模塊已經(jīng)完成了。我們可以在主程序中使用它。
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執(zhí)行腳本,然后等待’cooked’事件被觸發(fā),并在事件觸發(fā)之后調(diào)用回調(diào)函數(shù)并傳遞返回的參數(shù)。
還有什么要注意的
值得注意的是,例子中使用的“子類”和事件有一些極端(a bit of an overkill)。EventEmitter每次只觸發(fā)一個(gè)事件(EventEmitter for things that only fire one event once)。如果只創(chuàng)造少數(shù)幾個(gè)實(shí)例,可以將方法直接加入到實(shí)例本身,如果要觸發(fā)底層事件,可能實(shí)用異步函數(shù)會(huì)更好一些。
關(guān)于events.EventEmitter,你還需注意一個(gè)特別的事件:’error’。任何錯(cuò)誤發(fā)生時(shí)此事件都會(huì)觸發(fā),并且當(dāng)沒有監(jiān)聽程序監(jiān)聽這個(gè)事件時(shí),node將會(huì)拋出異常并結(jié)束應(yīng)用程序。(感謝Tim指出這一點(diǎn))
結(jié)束之前的話
這篇文章簡要介紹了一些好的方法(good runthrough)。在發(fā)表之前文章之前,我查閱了我最喜愛的圖書館,參考別人的實(shí)現(xiàn),并且還得到了別人的幫助弄把一些問題搞清楚。為了更好的理解node,我建議你閱讀Time Caswell的文章:
What is “this”? http://howtonode.org/what-is-this
同時(shí),你也可以看一下我用node.js寫的機(jī)器人混搭應(yīng)用(bot mashup)tocho,它使用了ircbot、logger、real-time websockets技術(shù)并支持搜索,但是處于開發(fā)的前期還比較粗糙。編寫這個(gè)程序給我?guī)砹撕芏鄻啡ぁN疫€沒有將搜索功能發(fā)布到演示網(wǎng)站,您以使用支持web socket的瀏覽器訪問實(shí)時(shí)聊天室#node.js。
原文:http://www.grati.org/?p=318
【編輯推薦】