關于異步 I/O ,向前端工程師解釋起來或許會容易一些,因為發起Ajax調用對于前端工程師而言是再熟悉不過的場景了。下面的代碼用于發起一個Ajax請求:
~~~
$.post('/url', {title:'深入淺出Node.js'}, function(data){
console.log('收到響應');
})
console.log('發送Ajax結束');
~~~
熟悉異步的用戶必然知道,“收到響應”是在“發送Ajax結束”之后輸出的。在調用 $.post() 后,后續代碼是被立即執行的,而“收到響應”的執行時間是不被預期的。我們只知道它將在這個異步請求結束后執行,但并不知道具體時間點。異步調用中對于結果值的捕獲是符合“Don't call me,I will call you”的原則的,這也是注重結果,不關心過程的一種表現。下圖是一個經典的Ajaxe調用:

在Node中,異步 I/O 也很常見。以讀取文件為例,我么可以看到它與前端Ajax調用的方式是極其類似的:
~~~
const fs = require('fs');
fs.readFile('/etc/passwd',(err, data)=>{
if(err) throw err;
console.log('讀取文件完成');
})
console.log('發起讀取文件');
~~~
這里的“發起讀取文件”是在“讀取文件完成”或 throw err 之前輸出的。同樣,“讀取文件完成”或 throw err 執行,也取決于讀取文件的異步調用何時結束。下圖是一個經典的異步調用:

在Node中,絕大多數的操作都是以異步的方式進行調用。Ryan Dahl排除萬難,在底層構建了很多異步 I/O 的API,從文件讀取到網絡請求等,均是如此。這樣的意義在于,在Node中,我們可以從語言層面很自然的進行 并行 I/O 操作。每個調用之間無需等待之前的 I/O 調用結束。在編程模型上可以極大提升效率。
下面的兩個文件讀取任務的耗時,取決于最慢的那個文件讀取的耗時:
~~~
fs.readFile('/path1',(err, data)=>{
console.log('讀取文件1完成');
});
fs.readFile('/path2',(err, data)=>{
console.log('讀取文件2完成');
});
~~~
而對于同步 I/O 而言,它們的耗時是兩個任務的耗時之和。這里異步帶來的優勢是顯而易見的。
關于異步I/O 如何提升效率及其本身的機制和實現,我們將在第3章中詳述。
- 目錄
- 第1章 Node 簡介
- 1.1 Node 的誕生歷程
- 1.2 Node 的命名與起源
- 1.2.1 為什么是 JavaScript
- 1.2.2 為什么叫 Node
- 1.3 Node給JavaScript帶來的意義
- 1.4 Node 的特點
- 1.4.1 異步 I/O
- 1.4.2 事件與回調函數
- 1.4.3 單線程
- 1.4.4 跨平臺
- 1.5 Node 的應用場景
- 1.5.1 I/O 密集型
- 1.5.2 是否不擅長CPU密集型業務
- 1.5.3 與遺留系統和平共處
- 1.5.4 分布式應用
- 1.6 Node 的使用者
- 1.7 參考資源
- 第2章 模塊機制
- 2.1 CommonJS 規范
- 2.1.1 CommonJS 的出發點
- 2.1.2 CommonJS 的模塊規范
- 2.2 Node 的模塊實現
- 2.2.1 優先從緩存加載
- 2.2.2 路徑分析和文件定位
- 2.2.3 模塊編譯
- 2.3 核心模塊
- 2.3.1 JavaScript核心模塊的編譯過程
- 2.3.2 C/C++核心模塊的編譯過程
- 2.3.3 核心模塊的引入流程
- 2.3.4 編寫核心模塊
- 2.4 C/C++擴展模塊
- 2.4.1 前提條件
- 2.4.2 C/C++擴展模塊的編寫
- 2.4.3 C/C++擴展模塊的編譯
- 2.4.2 C/C++擴展模塊的加載
- 2.5 模塊調用棧
- 2.6 包與NPM
- 2.6.1 包結構
- 2.6.2 包描述文件與NPM
- 2.6.3 NPM常用功能
- 2.6.4 局域NPM
- 2.6.5 NPM潛在問題
- 2.7 前后端共用模塊
- 2.7.1 模塊的側重點
- 2.7.2 AMD規范
- 2.7.3 CMD規范
- 2.7.4 兼容多種模塊規范
- 2.8 總結
- 2.9 參考資源
- 第3章 異步I/O
- 3.1 為什么要異步I/O
- 3.1.1 用戶體驗
- 3.1.2 資源分配
- 3.2 異步I/O實現現狀
- 3.2.1 異步I/O與非阻塞I/O
- 3.2.2 理想的非阻塞異步I/O
- 3.2.3 現實的異步I/O
- 3.3 Node的異步I/O
- 3.3.1 事件循環
- 3.3.2 觀察者
- 3.3.3 請求對象
- 3.3.4 執行回調
- 3.3.5 小結
- 3.4 非I/O的異步API
- 3.4.1 定時器
- 3.5 事件驅動與高性能服務器