前言
Node.js 是單進程單線程應用程序,但是因爲 V8 引擎提供的異步執行回調接口,通過這些接口可以處理大量的併發,所以性能非常高。
上一章我們說了NodeJs幾乎每一個 API 都是支持回調函數的,並且也介紹了回調函數。
Node.js 單線程類似進入一個 while(true)
的事件循環,直到沒有事件觀察者退出,每個異步事件都生成一個事件觀察者,如果有事件發生就調用該回調函數.
事件驅動程序
Node.js 使用事件驅動模型,當web server接收到請求,就把它關閉然後進行處理,然後去服務下一個web請求。當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給用戶。有沒有覺得很熟悉,有點類似 Js的事件循環
Go Javascript 事件循環。
Node.js 有多個內置的事件,我們可以通過引入 events 模塊,並通過實例化 EventEmitter 類來綁定和監聽事件
events 模塊只提供了一個對象: events.EventEmitter。EventEmitter 的核心就是事件觸發與事件監聽器功能的封裝
首先來說說 EventEmiter 類
Node.js 所有的異步 I/O 操作在完成時都會發送一個事件到事件隊列。
Node.js 裏面的許多對象都會分發事件, 所有這些產生事件的對象都是 events.EventEmitter 的實例。
實踐一下:
//event.js 文件
var EventEmitter = require('events').EventEmitter;
// new 一個 EventEmiter 類
var event = new EventEmitter();
// 監聽 some_event
event.on('some_event', function() {
console.log('some_event 事件觸發');
});
setTimeout(function() {
//觸發 some_event
event.emit('some_event');
}, 1000);
運行這段代碼,1 秒後控制檯輸出了 some_event 事件觸發
。其原理是 event
對象註冊了事件 some_event
的一個監聽器,然後我們通過 setTimeout
在 1000 毫秒以後向 event 對象發送事件 some_event
,此時會調用 some_event
的監聽器。
其實 eventEmiter
也是可以傳參數的,我們看下下邊這個例子
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 參數', 'arg2 參數');
結論:
1,EventEmitter 的每個事件由一個事件名和若干個參數組成
2,主要用來事件觸發與事件監聽
好,那麼我們說回事件循環
// 引入 events 模塊
var events = require('events');
// 創建 eventEmitter 對象
var eventEmitter = new events.EventEmitter();
// 定義一個處理程序函數 oneFun
function oneFun () {
console.log("hello one");
// 觸發事件 one
eventEmitter.emit('two');
}
// 定義一個處理程序函數 twoFun
function twoFun () {
console.log("hello two");
}
// 監聽事件 one 及事件的處理程序 oneFun
eventEmitter.on('one', oneFun);
// 監聽事件 one 及事件的處理程序 oneFun
eventEmitter.on('two', twoFun);
// 觸發事件 one
eventEmitter.emit('one');
運行結果
PS C:\HiSen\myWorkDemo\node_demo> node .\event_loop.js
hello one
hello two
PS C:\HiSen\myWorkDemo\node_demo>