絕大多數對Node.js的討論都把關注點放在了其處理高並發的能力上。簡單來說,相比其他同類解決方法,Node框架給開發這提供了構建高性能網絡應用的強大能力,當然,開發者要明白Node內部所作出的權衡,以及Node構建應用之所以性能好的原因。
Node.js為JavaScript引入了一個復雜的概念:共享狀態的並發。
因為Node采用一個長期運行的進程,每個請求共享這個進程,當這個變量被回調函數修改之后,結果就會改變。如PHP的Apache會產生出多個線程(每個請求對應一個線程),每次都會刷新,內部變量等就會重新賦值。所以對回調函數修改當前內存中的變量一定要非常小心,還要注意對錯誤的處理是否會潛在的修改這些狀態。
阻塞和非阻塞
當ajax同步處理的時候,必須等待服務器響應並返回頁面,才執行后續語句,這就是阻塞。Node.js采用了事件的輪詢,事件輪詢是非阻塞的。
什么是事件的輪詢,Node會注冊一個事件,掛到任務隊列中,然后不斷的詢問內核事件是否分發,當事件分發之后,就會觸發該事件的回調函數,然后繼續執行下去,如果沒有分發,就會繼續執行后續的語句。
console.log('hello'); setTimeout(function(){ console.log('world'); }, 500); console.log('bye'); //輸出 //hello //bye //world
單線程
如果想了解更多的運行機制,單線程,看大佬的文章:http://www.ruanyifeng.com/blog/2014/10/event-loop.html
錯誤處理
一個Http請求中,如果某個回調函數發生錯誤,整個進程都會遭殃,因為錯誤沒有被捕獲,進程的狀態就不確定。之后就可能無法正常工作,並且如果錯誤始終不處理的化,就會一直拋出意料之外的錯誤,這樣很難調試。
為什么try/catch 不會捕獲異常呢,因為異步機制,當異步時,catch代碼塊已經執行過后,異步的代碼才開始執行,一但出現錯誤,就不會被捕獲到。這時候就會觸發uncaughtException事件,直接終止當前棧,結果會導致所有用戶終止連接。
處理方法參考:http://www.infoq.com/cn/articles/quit-scheme-of-node-uncaughtexception-emergence/
絕大部分Node異步API接受回調函數,第一個參數都是錯誤對象或者null;