Node.js的特點:**只用一個線程來處理所有的請求,事件驅動編程**
* 店小二:線程
* 顧客:HTTP請求
* 第一類工作(迎客、找座、下單):在服務器端的代碼,能快速的執行
* 后廚做菜,客人吃飯:耗時的IO操作
* 后廚大喊一聲上菜:長時間IO操作之后發出的**事件**
* 結賬:另一個長時間IO操作完成后發出的**事件**
* 第二類工作(上菜、結賬):需要等待耗時的IO操作完成之后才能開始,也就是需要收到系統發出的**事件**之后才能開始執行。在Node.js中實際是在**回調函數**來執行
```
迎客 ();
找座 ();
下單 ();
后廚處理 ("做菜完成事件", function(){
上菜處理 ();
客人吃飯 ("吃飯完成事件",function(){
結賬處理 ();
送客 ();
});
});
```
需要注意的是:
* 后廚處理()這個函數需要接收兩個參數
1. 事件名:
2. 匿名回調函數,事件發生,回調函數才會執行
Node.js使用Chrome的V8引擎來執行JavaScript,效率非常高
* 代碼能否寫成?
```
迎客 ();
找座 ();
下單 ();
后廚處理 ("做菜完成事件", function(){
上菜處理 ();
});
客人吃飯 ("吃飯完成事件",function(){
結賬處理 ();
});
送客 ();
```
不能。
因為 Node.js 執行 "后廚處理 ()" 函數時,只是安插了一個匿名的回調函數在那里,并不會等待(非阻塞 I/O),反而馬上 會執行 “客人吃飯 ()" 函數,所以上述的寫法會引起邏輯上的錯誤: 還沒上菜就開始吃飯了!
所以寫慣了” 順序阻塞 I/O“的我們需要改變一下思維方式,進入到事件驅動的世界中來。
* 如果某個操作,比如說“上菜處理”是個CPU密集型的計算任務,Node.js那個唯一的線程就會忙于執行這個計算任務而被阻塞住了。后果是整個服務器就無法響應了。需要把這樣的代碼進行異步處理,也變稱Node.js所擅長的事件驅動方式