我們先來看看NodeJS官網上的介紹:
其特點為:
1,它是一個Javascript運行環境
2,依賴Chrome V8引擎進行程式碼解釋
3,事件驅動
4, 非阻塞I/O
5, 輕量、可伸縮,適於即時資料互動應用程式
6,單一進程,單執行緒
(1),Nodejs為什麼選擇javascript為載體語言
事實上,在實現Node.js 之初,作者Ryan Dahl 並沒有選擇JavaScript,他嘗試過C、Lua,皆因其欠缺一些高級語言的特性,如閉包、函數式編程,致使程序複雜,難以維護。
而 JavaScript 則是支援函數式程式設計範式的語言,很好地契合了 Node.js 基於事件驅動的程式設計模型。加之 Google 提供的 V8 引擎,使 JavaScript 語言的執行速度大幅提升。
最終呈現在我們面前的就成了 Node.js,而不是 Node.c,Node.lua 或其他語言的實作。
(2),Node.js不是JS應用、而是JS運行平台
看到Node.js這個名字,初學者可能會誤以為這是一個Javascript應用,事實上,Node.js採用C 語言編寫而成,是一個Javascript的運行環境。
Node.js採用了Google Chrome瀏覽器的V8引擎,效能很好,同時也提供了許多系統級的API,如檔案操作、網路程式設計等。
以下是NodeJS所涉及的全部模組:
瀏覽器端的Javascript程式碼在運作時會受到各種安全性的限制,對客戶系統的操作有限。
相比之下,Node.js則是一個全面的後台運行時,為Javascript提供了其他語言能夠實現的許多功能。
(3),Node.js的特點
Node.js在設計上也是比較創新,它以單一進程,單執行緒模式運作(這和Javascript的運作方式是一致的),
事件驅動機制是Node.js透過內部單執行緒高效維護事件循環佇列來實現的,沒有多執行緒的資源佔用和上下文切換,這意味著面對大規模的http請求,Node.js憑藉事件驅動搞定一切,
習慣了傳統語言的網路服務開發人員可能對多執行緒並發和協作非常熟悉,但是面對Node.js,我們需要接受和理解它的特點。
二,重要概念
1,什麼是 Event Loop ? (很重要的概念)
Event Loop 是一個很重要的概念,指的是電腦系統的一種運作機制。
想要理解Event Loop,就要從程式的運作模式講起。運行以後的程式叫做行程(Process),一般情況下,一個行程一次只能執行一個任務。
如果有許多任務需要執行,不外乎三種解決方法。
(1),排隊。因為一個行程一次只能執行一個任務,只好等前面的任務執行完了,再執行後面的任務。
(2),新流程。使用fork指令,為每個任務新建一個行程。
(3),新執行緒。因為行程太耗費資源,所以現今的程式往往允許一個行程包含多個線程,由執行緒去完成任務。
以JavaScript語言為例,它是一種單執行緒語言,所有任務都在一個執行緒上完成,也就是採用上面的第一種方法。一旦遇到大量任務或遇到耗時的任務,網頁就會出現"假死",因為JavaScript停不下來,也就無法回應使用者的行為。
你或許會問,JavaScript為什麼是單線程,難道不能實作為多線程嗎?
這跟歷史有關係:
JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。那麼,為什麼JavaScript不能有多個執行緒呢?這樣能提高效率啊。
JavaScript的單線程,與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單線程,否則會帶來複雜的同步問題。
比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準?
所以,為了避免複雜性,從一誕生,JavaScript就是單線程,這已經成了這門語言的核心特徵,將來也不會改變。
為了利用多核心CPU的運算能力,HTML5提出Web Worker標準,允許JavaScript腳本建立多個線程,但是子執行緒完全受主執行緒控制,且不得操作DOM。
所以,這個新標準並沒有改變JavaScript單線程的本質。
回到EventLoop:
單線程就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就得一直等著。
如果排隊是因為運算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO設備(輸入輸出設備)很慢(例如Ajax操作從網路讀取資料) ,不得不等著結果出來,再往下執行。
JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO設備,掛起處於等待中的任務,先執行排在後面的任務。等到IO設備回傳了結果,再回過頭,把掛起的任務繼續執行下去。
於是,所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是,在主執行緒排隊執行的任務,只有前一個任務執行完畢,
才能執行後一個任務;非同步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個非同步任務可以執行了,該任務才會進入主執行緒執行。
如下圖:
只要主執行緒空了,就會去讀取"任務佇列",這就是JavaScript的運作機制。這個過程會不斷重複。
三,實例講解
好了,「廢話」不多說了,馬上開始我們第一個NodeJS應用:「Hello 大熊」。
開啟你喜歡的編輯器,建立一個HelloWorld.js檔案。
程式碼如下:
我們來運行並且測試這段程式碼。首先,用Node.js執行你的腳本:
開啟命令列工具CMD,切換到你的工作目錄,執行指令「node HelloWorld.js」
接下來,打開瀏覽器訪問http://localhost:8888/,你會看到一個寫著 “Hello,大熊 !” 的網頁。
一點小的擴展知識:
如下圖所示,這是NodeJS中的http.js部分源碼,createServer是一個對用戶很友好的接口,內部實現採用了單例模式,這樣做的好處是,把實例的創建和初始化任務進行有效的分離,職責專一,降低耦合度,這是大家平常程式設計時可以藉鏡的想法。
哈哈哈,是不是很有意思,這只是一次短暫的體驗,後面會陸續講解很多的知識點,大家慢慢體會O(∩_∩)O哈哈~
四,總體概述
1,它是一個Javascript運行環境
2,依賴Chrome V8引擎進行程式碼解釋
3,事件驅動
4, 非阻塞I/O
5, 輕量、可伸縮,適於即時資料互動應用程式
6,單一進程,單執行緒
最後我想說的話是:這篇的例子不是很多,但是這些概念相當重要,一定要有一個清晰的理解,這樣為以後的NodeJS學習會打下牢固的基礎的,朋友們加油一起努力。
哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步。 。 。 。 。 。呼呼呼…(*^__^*)