node.js入門 - 8.api:events


  從今天開始,我們將介紹node的一些重要的api,首先向大家介紹的是events。他是node中相當重要的一個api,也是實現其他一些api的基礎,對他有好的理解,會幫助你使用好其他的api。

  如果你用javascript開發過瀏覽器的應用,那你一定很熟悉事件。但瀏覽器中的事件來源於dom,而不是javascript。dom中用戶驅動的事件通過一系列樹狀元素(html/xml)的接口實現與用戶的交互,當用戶和dom交互的時候就會產生相應的事件。

 

  1.EventEmitter

   node中不存在dom這個對象,所以他自己創建了EventEmitter類來實現基本的事件功能,node中其他事件的實現都是通過這個接口類實現的。EventEmitter中最重要的兩個方法是on和emit,來供其他類使用。on實現為事件實現監聽的功能,它有兩個參數,第一個是監聽的事件,第二個是相應的回調函數。來看一個例子:

server.on('event', function(a, b, c) {
  //do things
});

   EventEmitter是一個接口,所以我們需要創建一個繼承自它的類,使用新創建的類實現事件,而不是直接使用它。看下例:

var utils = require('utils'),
EventEmitter = require('events').EventEmitter;
var Server = function() {
  console.log('init');
};
utils.inherits(Server, EventEmitter);
var s = new Server(); s.on('abc', function() {   console.log('abc'); });

   通過上面的步驟,我們創建了Server類,並讓它繼承自EventEmitter,這樣我們就可以使用EventEmitter中相應的方法了。例如上面我們使用on監聽了一個叫做‘abc’的事件。那么我們如何才能觸發這個事件呢?用下面的語句即可。

s.emit('abc');

  這里需要強調的一點是,那些事件是實例級別的,不存在一個全局的事件,不同的Server的實例對象不能共享他們的事件。比如,上面的s對象就不能共享下面對象z的事件,

var z = new Server();.

 

  2.Callback

  使用事件,一個很重要的內容是使用回調函數,下面我們來了解下node中回調函數的機制。

  在使用emit方法的時候,除了事件名稱這個參數之外,我們還可以添加任意一些其他的參數,例如:

s.emit('abc', a, b, c);

  其他的一些參數會傳遞給回調函數。當我們使用emit方法的時候,下面的代碼會去訪問每一個監聽的事件。

if (arguments.length <= 3) {
  // fast case
  handler.call(this, arguments[1], arguments[2]);
} else {
  // slower
  var args = Array.prototype.slice.call(arguments, 1);
  handler.apply(this, args);
}

  根據參數的長短,代碼會選擇是使用call還是使用apply。請注意第一個參數this,這意味着訪問事件監聽器的上下文是EventEmitter的上下文,而不是代碼原先的上下文。使用node REPL,你會看到使用EventEmitter到底發生了什么。運行【開始】菜單,選擇【所有程序】,找到【Node.js (x86)】,點【Node.js】,逐行輸入下面內容(換行使用shift+回車),也可以使用粘貼復制的方式輸入:

var EventEmitter = require('events').EventEmitter,util = require('util');

var Server = function() {};
util.inherits(Server, EventEmitter);
Server.prototype.outputThis= function(output) {
  console.log(this);
  console.log(output);
};

Server.prototype.emitOutput = function(input) {   this.emit('output', input); }; Server.prototype.callEmitOutput = function() {   this.emitOutput('innerEmitOutput'); };
var s = new Server(); s.on('output', s.outputThis); s.emitOutput('outerEmitOutput'); s.callEmitOutput(); s.emit('output', 'Direct');

  結果:

   注意到藍線部分,這部分就是console.log(this)輸出的內容,看的出this不論在那種情況下,指向的都是EventEmitter對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM