我們先來看看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檔案。
代碼如下:
複製代碼 代碼如下:
1 var http = require("http") ;2 http.createServer(function(request,response){3 response.writeHead(200,{4 "Content-Type" : "text/plain"5 }) ;6 response.write("Hello,大熊 !") ;7 response.end() ;8 }).listen(8888) ;
我們來運行並且測試這段代碼。首先,用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學習會打下牢固的基礎的,朋友們加油一起努力。
哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步。。。。。。呼呼呼……(*^__^*)