天天看點

大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)

一,開篇分析

大家好啊,大熊君又來啦(*^__^*) 嘻嘻……,之前我寫過一系列關于JS(OOP與設計模式)方面的文章,反響還好,其實這也是對我本人最大的鼓勵,于是我決定我要将JavaScript進行到底

準備寫一個NodeJS方面的系列文章,由淺入深,循序漸進,秉承的理念是重思想,多實踐,勤能補拙,貴在堅持。

我們先來看看NodeJS官網上的介紹:

大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)

  其特點為:

  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所涉及的全部子產品:

    

大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)
大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)

    浏覽器端的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)的任務,隻有"任務隊列"通知主線程,某個異步任務可以執行了,該任務才會進入主線程執行。

      如下圖:

        

大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)

       隻要主線程空了,就會去讀取"任務隊列",這就是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是一個對使用者很友好的接口,内部實作采用了單例模式,這樣做的好處是,把執行個體的建立和初始化任務進行有效的分離,職責專一,降低耦合度,這是大家平時程式設計時可以借鑒的思想。

大熊君大話NodeJS之開篇------Why NodeJS(将Javascript進行到底)

  哈哈哈,是不是很有意思,這隻是一次短暫的體驗,後面會陸續講解很多的知識點,大家慢慢體會O(∩_∩)O哈哈~

四,總體概述

  最後我想說的話是:這篇的例子不是很多,但是這些概念相當重要,一定要有一個清晰的了解,這樣為以後的NodeJS學習會打下牢固的基礎的,朋友們加油一起努力。

        哈哈哈,本篇結束,未完待續,希望和大家多多交流夠溝通,共同進步。。。。。。呼呼呼……(*^__^*)            

繼續閱讀