非阻塞I/O事件驅動

在 Java、PHP 或者.net 等服務器端語言中,會爲每個客戶端鏈接建立一個新的線程。而每一個線程須要耗費大約 2MB 內存。也就是說,理論上,一個 8GB 內存的服務器能夠同時鏈接的最大用戶數爲 4000 個左右。要讓 Web 應用程序支持更多的用戶,就須要增長服務器的數量,而 Web 應用程序的硬件成本固然就上升了。node.js 不爲每一個客戶鏈接建立一個新的線程,而僅僅使用一個線程。當有用戶鏈接了,就觸發一個內部事件,經過非阻塞 I/O、事件驅動機制,讓 Node.js 程序宏觀上也是並行的。使用 Node.js,一個 8GB 內存的服務器,能夠同時處理超過 4 萬用戶的鏈接。node

可是在實際過程當中,非阻塞也會產生必定的問題,例如,咱們須要從後臺請求數據,而後拿到這些數據之後,執行某些操做,可是因爲非阻塞,不能控制獲取數據的時間,後續的操做就會出現問題。數組

在上面例子中,咱們但願先執行第一個打印,而後執行文件讀取,最後執行第四個打印。可是因爲Node是非阻塞的,在執行到文件讀取的時候,因爲文件大小的緣由,須要必定的時間,在這個時間裏,有並行處理了第四個打印,等第四個打印執行了,前面的文件讀取才執行結束,因而就有了下面的輸出服務器

一樣,在下面的例子中,一樣因爲執行文件讀取的時間過長,在讀取文件的時候,併發執行了打印事件,因此打印的時候,並無數據。併發

      

但是在實際項目中,這種結果是不能接受的,爲了保證能打印出數據,咱們但願在文件結束後,再執行打印事件,下面兩種辦法就是實現這個要求。異步

回調函數

    

event模塊處理異步

Node.js 有多個內置的事件,咱們能夠經過引入 events 模塊,並經過實例化 EventEmitter 類來綁定和監聽事件。函數

在使用events 模塊的時候,須要先引入改模塊,並建立 EventEmitter對象。ui

var events=require('events');
var EventEmitter=new events.EventEmitter();

而後在須要等待上面執行完畢再執行的事件裏面,綁定事件和事件處理程序spa

eventEmitter.on('eventName', eventHandler);

最後,在處理費時程序的地方,觸發上面的綁定.net

eventEmitter.emit('eventName');

綁定和觸發的事件名稱須要保持一致。線程

按照上面的方式,咱們能夠對前面的例子進行調整:

    

event模塊

Node.js 全部的異步 I/O 操做在完成時都會發送一個事件到事件隊列,全部這些產生事件的對象都是 events.EventEmitter 的實例,EventEmitter 的核心就是事件觸發與事件監聽器功能的封裝。EventEmitter 對象若是在實例化時發生錯誤,會觸發 error 事件。當添加新的監聽器時,newListener 事件會觸發,當監聽器被移除時,removeListener 事件被觸發。

基礎用法

  

多個監聽器

EventEmitter 的每一個事件由一個事件名和若干個參數組成,事件名是一個字符串,一般表達必定的語義。對於每一個事件,EventEmitter 支持 若干個事件監聽器。當事件觸發時,註冊到這個事件的事件監聽器被依次調用,事件參數做爲回調函數參數傳遞。

   

相關文章
相關標籤/搜索