Node.js中非阻塞IO和事件迴圈
首先,IO操作無疑是耗時的,當伺服器端接收到大量請求時,為每一個請求建立程式或執行緒的同時,也增加了額外的記憶體開銷,也可能浪費更多的時間資源。由於Node.js是事件驅動的,於是它使用了事件迴圈來解決IO操作帶來的瓶頸問題。在Node.js中,一個IO操作通常會帶有一個回撥函式,當IO操作完成並返回時,就會呼叫這個回撥函式,而主執行緒則繼續執行接下來的程式碼。
簡單的用一個例子來說明這個問題:
[JavaScript] 純文字檢視 複製程式碼request('http://www.google.com', function(error, response, body) { console.log(body); }); console.log('Done!');
這段程式碼的意思是向'http://www.google.com'發出請求,當請求返回這則呼叫回撥函式輸出響應資訊。由於Node.js的執行機制,這段程式碼執行後,會立即在控制檯輸出'Done!',然後一段時間後再輸出響應的資訊。
事件迴圈event loop:
接下來,來討論下事件迴圈的機制。首先說說呼叫桟,比如有如下一段程式碼:
[JavaScript] 純文字檢視 複製程式碼function A(arg, func){ var a = arg; func(); console.log('A'); } function B(){ console.log('B'); } A(0, B);
當程式碼執行後,函式A首先被推入呼叫桟中成為棧頂元素並開始執行A,在執行過程中函式B又被推入呼叫桟成為棧頂元素,在B執行完成後,B被彈出呼叫桟,A再次成為棧頂元素,在A執行完成後A被彈出呼叫桟,呼叫桟呈空閒狀態。
在Javascript執行時中存在一個訊息佇列,而訊息和一個回撥函式相關聯,當一個事件被觸發時,如果這個事件有相應的回撥函式,則該訊息就會被加入到訊息佇列中去。
回過頭來說事件迴圈到底迴圈的是什麼,在程式碼開始執行後,函式被不斷推入呼叫桟中,就拿上面的例子來講,request被推入呼叫桟中,這個函式將進行一個http請求(這個http請求將交由Node.js的底層模組來實現)同時請求完成的事件和一個回撥函式關聯起來,request被彈出呼叫桟,console.log被推入呼叫桟開始執行。當請求完成時,完成事件被觸發,一條訊息被新增進訊息佇列中,訊息佇列首先會檢查呼叫桟是否為空閒狀態,如果呼叫桟並不空閒,則會一直等待到呼叫桟空閒狀態後,將訊息佇列的頭部彈出,此時與該訊息相關聯的回撥函式被執行。
最後總結:
以上就無阻塞模型和事件迴圈在概念上進行了總結。而這個事件迴圈的機制並不僅僅是Node.js所獨有的,並且Node.js的程式碼是單執行緒執行的,在面對大量併發請求的時候,又有著什麼優勢呢?
上面這張圖展示了Node.js的架構圖,Node.js的底層有一個模組負責維護執行緒池,當一個IO請求發出的時候,Node.js的底層模組將新建一個執行緒來處理請求,完成後再將結果交還給上層。那麼,當有多個請求的時候,Node.js的底層模組將利用盡可能少的執行緒來完成最多的任務,如果存在空閒的執行緒,它將繼續被利用來做其他的事情,這對於前面說的針對每個請求開一個新的程式或執行緒而言,無疑“聰明”許多,也更加高效了。
相關文章
- Node - 非同步IO和事件迴圈非同步事件
- Node.js 事件迴圈的完整指南Node.js事件
- Node.js 的事件迴圈機制Node.js事件
- Node.js 事件迴圈-比官方更全面Node.js事件
- nodejs事件和事件迴圈詳解NodeJS事件
- nodejs事件和事件迴圈簡介NodeJS事件
- 理解瀏覽器和node.js中的Event loop事件迴圈瀏覽器Node.jsOOP事件
- Node.js中的事件迴圈,Timers和process.nextTick() 的探索之路Node.js事件
- [譯]Node.js中的事件迴圈,定時器和process.nextTick()Node.js事件定時器
- FastAPI之阻塞式io和非阻塞式ioASTAPI
- 事件迴圈事件
- UNIX epoll 與 Node.js 事件迴圈多路分解器Node.js事件
- node的事件迴圈和瀏覽器的事件迴圈有什麼區別?事件瀏覽器
- IO模式和IO多路複用(阻塞IO、非阻塞IO、同步IO、非同步IO等概念)模式非同步
- JS事件迴圈JS事件
- nodejs事件迴圈NodeJS事件
- libuv事件迴圈事件
- 阻塞IO與非阻塞IO
- 深入分析Node.js事件迴圈與訊息佇列Node.js事件佇列
- Java 非阻塞 IO 和非同步 IOJava非同步
- 詳談javascript和node的事件迴圈JavaScript事件
- 事件迴圈詳解事件
- 事件迴圈(event loop)事件OOP
- Linux 阻塞和非阻塞 IO 實驗學習Linux
- JavaScript事件迴圈(Event Loop)JavaScript事件OOP
- JavaScript 事件迴圈機制JavaScript事件
- JavaScript-事件迴圈-eventLoopJavaScript事件OOP
- Node中的事件迴圈事件
- 剖析nodejs的事件迴圈NodeJS事件
- 聊聊Javascript的事件迴圈JavaScript事件
- Redis 中的事件迴圈Redis事件
- Javascript 事件迴圈event loopJavaScript事件OOP
- JS事件迴圈Event LoopJS事件OOP
- Nodejs事件迴圈小記NodeJS事件
- JS 事件迴圈(Event Loop)JS事件OOP
- JavaScript事件迴圈機制JavaScript事件
- 淺談Javascript單執行緒和事件迴圈JavaScript執行緒事件
- [作業系統]阻塞io 非阻塞io Epoll作業系統
- 阻塞式IO