深入淺出nodeJS
內容
1.Node簡介
2.模組機制
3.非同步I/O
4.非同步程式設計
5.記憶體控制
6.理解Buffer
7.網路程式設計
8.構建Web應用
9.玩轉程序
10.測試
11.產品化
一、Node簡介
1.Node的特點
- 非同步I/O
- 事件與回撥函式
-
單執行緒
弱點:
1)無法利用多核CPU
2)錯誤會引起整個應用退出,應用的健壯性值得考驗。
3)大量計算佔用CPU導致無法繼續呼叫非同步I/O。 - 跨平臺
2.Node的應用場景
- I/O密集型
- 是否不擅長CPU密集型業務
- 與遺留系統和平共處
- 分散式應用
3.Node的使用者
- 前後端程式語言環境統一
- Node帶來的高效能I/O用於實時應用
- 並行I/O使得使用者可以更高效地利用分散式環境
- 並行I/O,有效利用穩定介面提升Web渲染能力
- 雲端計算平臺提供Node支援
- 遊戲開發領域。
- 工具類應用
二、模組機制
1.CommonJs規範
主要分為以下三個部分
-
模組引用
require()方法接受模組標識,以此引入一個模組的API到當前上下文中
var math=require('math');
-
模組定義
exports物件用於匯出當前模組的方法或變數,並且它是唯一匯出的出口。
module物件,它代表模組本身,exports是module的屬性。
在node中,一個檔案就是一個模組,將方法掛載在exports物件上作為屬性即可定義匯出的方式
//math.js exports.add=function(){ return 'aaaa' } // program.js var math=require('math'); var a=math.add();//aaa
-
模組標識
模組標識就是傳遞給require()方法的引數,
它必須是符合小駝峰命名的字串,或者以.、..開頭的相對路徑,或是絕對路徑,可以沒有檔名字尾.js
2.Node的模組實現
在node中引入模組,需要經歷如下三個步驟
- 路徑分析
- 檔案定位
- 編譯執行
模組分為兩類:
- 核心模組:node提供的模組。在node原始碼的編譯過程中,編譯進了二進位制執行檔案,載入速度快。
- 檔案模組:使用者編寫的模組。執行時動態載入,速度比較慢。
1)優先從快取中載入
node 對引入過的模組都會進行快取,以減少二次引入時的開銷,快取的是編譯和執行之後的物件
require()方法對相同的模組二次載入都一律採用快取優先的方式,核心模組的檢查先於檔案模組的快取檢查
2)路徑分析和檔案定位
-
模組識別符號分析:
載入速度:核心模組 > 路徑形式的檔案模組 > 自定義模組 -
檔案定位:
副檔名分析:如果識別符號中不包含副檔名,則按.js 、.json 、.node 的次序補足副檔名。
目標分析和包:如果沒有查詢到對應檔案,但卻得到一個目錄,此時node會將目錄當做一個包來處理
3)模組編譯
對於不同的副檔名,載入方法不同,具體如下:
- .js檔案:通過fs模組同步讀取檔案後編譯執行
- .node檔案:這是用C/C++編寫的擴充套件檔案,通過dlopen()方法載入最後編譯生成的檔案
- .json檔案:通過fs模組同步讀取檔案後,用JSON.parse()解析返回結果
- 其餘擴充套件檔案。它們都被當做.js檔案載入
require.extensions:獲取系統中已有的擴充套件載入方式。
編譯方式:
-
JavaScript模組的編譯:
在編譯過程中,對js內容進行了包裝
執行之後,exports屬性被返回了呼叫方,被外部呼叫
(function(exports,require,module,__filename,__dirname){
// 內容 var math=require('./math'); var a=math.add();
})
-
C/C++模組的編譯
呼叫dlopen()方法進行載入和執行 -
JSON檔案的編譯
通過fs模組同步讀取檔案後,用JSON.parse()得到物件,然後將它賦給模組物件的exports,以供外部呼叫
3.核心模組
核心模組分為兩部分:C/C++編寫(檔案放在Node專案的src目錄下),JavaScript編寫(檔案放在Node專案的lib目錄下)。
1)JavaScript核心模組的編譯過程