Node.js應該是當今最火熱的技術之一。本文主要介紹Node.js的特色及應用場景。
Node.js是一個基於Chrome JavaScript運行時建立的一個平台,用來方便地建立快速的 易於擴展的網路應用。 Node.js借助事件驅動,非阻塞I/O模型變得輕量且高效,非常適合 運行在分散式設備的資料密集型即時應用。
1. 特點
1.1 非同步I/O
所謂的非同步I/O,是相對同步I/O而言的。程式執行過程中必然要進行許多I/O操作,如讀寫檔、輸入輸出、請求回應等等。通常來說,I/O操作是非常耗時的。例如在傳統的程式模式中,你要讀一個幾G的文件,整個執行緒都暫停下來,等待文件讀完後繼續執行。換言之,I/O操作阻塞了程式碼的執行,大大降低了程式的效率。
關於非同步I/O,其實對於前端工程師來說並不陌生,因為發起Ajax請求就是最常見的一種「非同步」呼叫。在Node中,以讀取檔案(讀取檔案是一種耗時的I/O操作)為例,它與發起Ajax請求的寫法很像:
上述程式碼在呼叫fs.readFile後,後續程式碼是立即執行的,而「讀取檔案完成」的時刻是無法預測的。當執行緒遇到I/O操作時不會以阻塞的方式等待I/O操作結束,而只是將I/O請求傳送給作業系統,繼續執行後續語句。當作業系統完成I/O操作時以事件的形式通知執行I/O操作的線程,線程會在特定時間處理這個事件。
1.2 事件循環與回呼函數
所謂事件循環是指Node會把所有的非同步操作使用事件機制解決,有個執行緒不斷地循環偵測事件隊列。事件循環會檢查事件佇列中有沒有未處理的事件,直到程式結束。事件的程式設計方式具有輕量級、鬆散耦合、只關注事務點等優勢,但是在多個非同步任務的場景下,事件與事件之間各自獨立,如何協作是一個問題。在Javascript中,回呼函數無所不在,回呼函數是最好的接受非同步呼叫回傳資料的方式。
1.3 單線程
Node保持了JS在瀏覽器中單執行緒的特性。單執行緒的最大好處是不用像多執行緒程式設計那樣出處在意狀態的同步問題,沒有死鎖的存在,也沒有執行緒上下文切換的開銷。單執行緒也有其弱點,主要表現在三個方面:無法利用多核心CPU;錯誤會造成整個應用程式退出,應用的健全性值得考研;大量運算會佔用CPU導致無法繼續呼叫非同步I/O。
為了解決上述問題,Node採用了與HTML5 Web Workers相同的思路,使用child_process來解決但單線程中大計算量的問題。透過將計算分發到各個子進程,可以將大量計算分解掉,然後再透過進程之間的事件訊息來傳遞結果。
1.4 跨平台
Node是跨平台的,也就是同樣的一套JS程式碼都可以部署運行在Windows、Linux、OSX等平台。這主要得益於Node在作業系統與Node上層模組系統之間建構了一層平台層架構libuv。
2. 應用場景
1)、即時應用:如線上聊天,即時通知推播等等(如socket.io)
2)、分散式應用:透過高效率的並行I/O使用已有的資料
3)、工具類應用:海量的工具,小到前端壓縮部署(如grunt),大到桌面圖形介面應用程式
4)、遊戲類應用:遊戲領域對即時和並發有很高的要求(如網易的pomelo框架)
5)、利用穩定介面提升Web渲染能力
6)、前後端程式語言環境統一:前端開發人員可以非常快速地切入到伺服器端的開發(如著名的純Javascript全端式MEAN架構)