引言:Node 已經迅速成爲一個可行而且真正高效的web 開發平臺。在Node 誕生以前,在服務端運行JavasScript 是件難以想象的事情,而且對其餘的腳本語言來講,要實現非阻塞I/O 一般須要依賴特殊的類庫。但Node 的出現改變了這一切。 本文選自《Node.js硬實戰:115個核心技巧》,讓咱們跟着本文快速的複習一下Node是什麼以及他的主要特性有哪些。
假設你正在開發一個廣告服務器,每分鐘須要發佈幾百萬條的廣告。Node 的非阻塞I/O將是一個高效的解決方案,由於服務器可以最大限度地利用到全部的I/O 資源,而這一切不須要你寫特殊的底層代碼。而且,假如你已經有一支會寫JavaScript 的開發團隊,那麼他們應該能夠直接參與到Node 的項目中。傳統的web 平臺將沒法作到這一點,這也是爲何像微軟這樣的公司也在積極地推進Node,儘管他們已經有了像.NET 那麼優秀的平臺。Visual Studio(.NET IDE) 的用戶能夠安裝一些工具來支持對Node 的智能提示、性能監測,甚至npm。微軟還開發了WebMatrix,它不但能直接支持Node,並且還能部署Node 項目。
Node 把非阻塞I/O 做爲提升某些類型應用的性能的方式。JavaScript 傳統的事件機制意味着在異步編程中,它有着相對方便以及容易理解的語法。在傳統的編程語言中,I/O的操做將阻塞進程直到它完成爲止。Node 的異步文件讀寫以及網絡API 意味着在這些相對較慢的I/O 操做處理的時候主進程仍然能處理其餘請求。下圖展現瞭如何使用異步的網絡和文件API 同時處理多個任務。
在圖中,Node 的http 模塊接收到而且解析了一個新的HTTP 請求① ,而後服務端的應用代碼使用異步接口,將一個回調函數傳入數據庫的讀取函數中來進行一次數據查詢②。在等待數據返回的同時服務器可以從文件系統中讀取網頁模板文件③ ,這個模板文件被用來展現網頁。一旦數據庫完成查詢,模板內容和數據庫的返回數據將被用來渲染頁面④。
在服務器處理這個請求的同時,服務器還能夠用可用的資源處理其餘的請求⑤ 。在不用考慮多線程的狀況下開發這個廣告服務,你能夠僅使用最基本的JavaScript 編程技術,經過Node,很是高效地使用服務器I/O 資源。
其餘Node 適用的場景是Web API 和網絡爬蟲,若是你須要下載以及截取網頁的內容,那麼Node 將是很是完美的解決方案,由於它能模擬DOM 操做,而且運行客戶端JavaScript腳本。並且在這個場景中,Node 有着性能優點,由於網絡爬蟲主要的消耗在於網絡和文件讀寫的I/O。
假如你須要調用或者開發一個JSON API,Node 也是一個很是棒的選擇,由於它使得操做JavaScript 對象變得很是簡單。Node 的一些web 框架(例如express)可以快速地搭建JSON API。
Node 不只僅侷限於web 應用,你能夠建立任意你想要的TCP/IP 服務,好比網絡遊戲服務器,經過TCP/IP 套接字向各種玩家發送遊戲狀態,也能夠在後臺任務中維護遊戲數據,將數據發送給玩家。web
下面是一些Node 適用的應用例子,來幫你像一個真正的Node 開發者同樣來考慮這個問題。數據庫
Node 的強項:
• 有效地分配小塊信息
• 處理潛在的網絡速度慢的鏈接
• 容易擴展爲多個處理器或服務器express
Node 的強項:
• 使用JavaScript 來構建業務邏輯模型
• 不使用C 語言來開發迎合特定網絡的服務器程序npm
Node 的強項:
• 對已經有客戶端JavaScript 開發經驗的團隊來講,能夠很輕鬆地建立RESTful JSON APIs
• 輕量的服務器,和瀏覽器端JavaScript 結合編程
Node 的主要特性是它的標準類庫、模塊系統以及npm(包管理系統),固然還有不少其餘的。
實際上Node 最強大的特性是它的標準類庫,它主要由二進制類庫以及核心模塊兩部分組成,二進制類庫包括libuv ,它爲網絡以及文件系統提供了快速的事件輪循以及非阻塞的I/O。同時它還有http 類庫,因此你能夠很快肯定你的http 客戶端與服務端。
上圖是對Node 內部的高層次概述,展現了各個模塊是如何組合的。
Node 的核心模塊主要由JavaScript 編寫,也就是說,假如你不理解或者你想了解更多細節,你能夠直接閱讀Node 的源碼。這不但包括像網絡、文件操做、模塊系統,以及stream 這些模塊,還包括Node 特有的特性,例如,經過cluster 模塊同時運行多個Node進程,以及能夠將代碼片斷封裝在事件驅動的異常處理中的domain 模塊。
接下來,咱們將從事件開始深刻每一個核心模塊。瀏覽器
每一個Node 開發者早晚會碰到EventEmitter ,一開始,它像是那些只有類庫開發者纔會使用的東西,但實際上它是大多數Node 核心模塊的基礎,Stream、網絡、文件系統所有繼承於它。
你能夠基於EventEmitter 來建立本身基於事件的API,例如你要開發一個paypal 付款處理的模塊,你可讓它基於事件,這樣Payment 對象的實例能夠觸發像paid 和refund 這樣的事件,經過這樣的設計,你能夠將這個模塊從你的業務邏輯中分離出來,讓它能夠在其餘項目中被重用。
一個有意思的地方是,stream 模塊也是基於EventEmitter 的。安全
Streams 繼承於EventEmitters ,能被用來在不可預測的輸入下建立數據,好比網絡鏈接,數據傳輸速度取決於其餘用戶正在幹什麼。經過Node 的stream API,你能夠建立一個對象接收關於鏈接的事件,在接收到新數據時觸發data 事件,在結束鏈接時觸發end 事件,在有錯誤發生時觸發error 事件。
相比較把許多的回調函數傳入一個readable stream 的構造函數,你只訂閱你關心的事件要好得多,多個streams 也能夠鏈接起來,這樣你能夠用一個stream 對象從網絡讀取數據,把讀取到的數據輸送到另一個stream 中加工成另一個對象,能夠把xml 文件的數據讀取出來轉換成JSON 格式,讓JavaScript 操做起來更容易。
你可能以爲stream 和事件聽上去很抽象,沒錯,它們的確很抽象,但它們是I/O 模塊(例如文件系統和網絡)的基礎。服務器
Node 的文件模塊不但能夠經過非阻塞的I/O 讀寫文件,並且它也有同步的方法。你能夠經過fs.stat 異步獲取文件的信息,也能夠經過fs.statSync 同步讀取。
若是你想經過Stream 的方式高效地處理文件內容,那麼你能夠經過fs.createReadStream來得到一個ReadableSream 對象。微信
網絡模塊是http 模塊的基礎,也能夠用來建立通用的網絡客戶端與服務端。儘管Node開發一般指的是web 開發,在第7 章你會看到如何建立TCP 和UDP 的服務,這意味着你並不侷限於http 開發。網絡
假如你有用Node 開發web 應用的經驗,也許是Express 框架,那麼你也許並不知道你已經使用了http 、net 以及fs 等核心模塊。其餘的內置模塊也許不那麼吸引眼球,但也是相當重要的。
全局對象與方法的設計就是其中一例,好比process 對象,它讓你能夠把數據傳入或者傳出標準I/O 流(stdout、stdin)。就像在UNIX 或者Windows 腳本中,你能夠把數據經過cat 直接傳給Node 程序。還有無處不見的console 對象,全部的JavaScript 開發都愛它,也是一個全局對象。
瞭解Node特性後,咱們來看看《Node.js硬實戰:115個核心技巧》一書的精簡版目錄。
第一部分Node 基礎
1 入門
2 全局變量:Node 環境
3 Buffers:使用比特、字節以及編碼
4 Events:玩轉EventEmitter
5 流:最強大和最容易誤解的功能
6 文件系統:經過異步和同步的方法處理文件
7 網絡:Node 真正的「Hello, World」
8 子進程:利用Node 整合外部應用程序
第二部分實踐中的技巧
9 網絡:構建精簡的網絡應用
10 測試:編寫健壯代碼的關鍵
11 調試:用於發現和解決問題
12 生產環境中的Node:安全地部署應用程序
第三部分編寫模塊
13 編寫模塊,掌握Node 的全部