深入淺析Node.js 事件迴圈_node.js

來源:互聯網
上載者:User

Node.js 是單進程單線程應用程式,但是通過事件和回調支援並發,所以效能非常高。

(來源於Javascript是單線程又是非同步,但是這種語言有個共同的特點:它們是 event-driven 的。驅動它們的 event 來自一個異構的平台。)

Node.js 的每一個 API 都是非同步,並作為一個獨立線程運行,使用非同步函數調用,並處理並發。

Node.js 基本上所有的事件機制都是用設計模式中觀察者模式實現。

Node.js 單線程類似進入一個while(true)的事件迴圈,直到沒有事件觀察者退出,每個非同步事件都產生一個事件觀察者,如果有事件發生就調用該回呼函數.

事件驅動模型

Node.js 使用事件驅動模型,當webserver接收到請求,就把它關閉然後進行處理,然後去服務下一個web請求。

當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給使用者。

這個模型非常高效可擴充性非常強,因為webserver一直接受請求而不等待任何讀寫操作。
(這也被稱之為非阻塞式IO或者事件驅動IO)

在事件驅動模型中,會產生一個主迴圈來監聽事件,當檢測到事件時觸發回呼函數。

整個事件驅動的流程就是這麼實現的,非常簡潔。有點類似於觀察者模式,事件相當於一個主題(Subject),而所有註冊到這個事件上的處理函數相當於觀察者(Observer)。

Node.js 有多個內建的事件,我們可以通過引入 events 模組,並通過執行個體化 EventEmitter 類來綁定和監聽事件,如下執行個體:

//引入events模組var events = require('events');//建立eventEmitter對象var eventEmitter = new events.EventEmitter();//建立事件處理常式var connectHandler = function connected() { console.log('串連成功。'); //觸發data_received事件  eventEmitter.emit('data_received');}//綁定connection事件處理常式eventEmitter.on('connection', connectHandler);//使用匿名函數綁定data_received事件eventEmitter.on('data_received', function(){ console.log('資料接收成功。');});//觸發connection事件 eventEmitter.emit('connection');console.log("程式執行完畢。"); 

以上代碼輸出的結果是:

串連成功。

資料接收成功。

程式執行完畢。

上述的結果正如你想的一樣,通過這種事件驅動模型我們就可以實現非同步作業的。

(例如,我們可以一邊讀取檔案,一邊執行其他命令,在檔案讀取完成後,我們將檔案內容作為回呼函數的參數返回。這樣在執行代碼時就沒有阻塞或等待檔案 I/O 操作。這就大大提高了 Node.js 的效能,可以處理大量的並發請求。)

var fs = require("fs");fs.readFile('input.txt', function (err, data) { if (err){ console.log(err.stack); return; } console.log(data.toString());});console.log("程式執行完畢。"); 

以上代碼輸出的結果是:

程式執行完畢。

input.txt的內容。

從上述代碼可以看出fs.readFile可以分發事件,當然Node.js裡面的許多個物件都會分發事件,一個net.Server對象會在每次有新串連時也會分發一個事件, 所有這些產生事件的對象都是 events.EventEmitter 的執行個體。

不過大多數時候我們不會直接使用 EventEmitter,而是在對象中繼承它。包括 fs、net、 http 在內的,只要是支援事件響應的核心模組都是 EventEmitter 的子類。

為什麼要這樣做呢?原因有兩點:

首先,具有某個實體功能的對象實現事件符合語義, 事件的監聽和發射應該是一個對象的方法。
其次 JavaScript 的對象機制是基於原型的,支援 部分多重繼承,繼承 EventEmitter 不會打亂對象原有的繼承關係。

下面給大家分享我的第一個NodeJs項目

Node.js的安裝通常有兩種方式:自己編譯原始碼和使用編譯好的檔案,我這裡使用編譯好的檔案
目前我的home目錄下有剛下載來的node-v4.2.3-linux-x64

1.首先解壓縮

複製代碼 代碼如下:

tar xvf node-v4.2.3-linux-x64

2.設定連結,設定連結的目的在於任何路徑都能夠用到node命令

複製代碼 代碼如下:

ln -s /home/node-v4.2.3-linux-x64/bin/node /usr/local/bin/node
ln -s /home/node-v4.2.3-linux-x64/bin/npm /usr/local/bin/npm

3.在home檔案夾下建個目錄叫mynodeproj,然後再建了個檔案叫server.js(當然也可以起別的名字)

var http = require('http');http.createServer(function (request, response) { //發送 HTTP 頭部  //HTTP 狀態值: 200 : OK //內容類型: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); //發送響應資料 "Hello World" response.end('Hello World\n');}).listen(8888);//終端列印如下資訊console.log('Server running at http://127.0.0.1:8888/'); 

4.使用node命令執行以上代碼

node server.js

執行上述命令之後會在命令列中顯示"Server runnint at http://127.0.0.1:8888/",這樣表示程式已經執行成功了!

因為我這個伺服器是在阿里雲裡跑起來的,所以只要在外面的瀏覽器中鍵入阿里雲IP+連接埠就可以訪問了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.