我們先來看看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學習會打下牢固的基礎的,朋友們加油一起努力。
哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步。。。。。。呼呼呼……(*^__^*)