基本概念
<font face="新宋体">Node.js</font>
,或 Node,是一個可以讓 <font face="新宋体">JavaScript</font>
運行在伺服器端的平台。可以說,<font face="新宋体">Node.js</font>
開創了<font face="新宋体">javascript</font>
模組化開發的先河,早期的<font face="新宋体">javascript</font>
需求都很簡單,基本上都是寫成函數的,然後是面向過程的寫法,後來慢慢的引入面向對象開發思想,再後來慢慢寫成類別。最後node.js的出現才開始有了js模組化開發的概念,這使得臃腫的<font face="新宋体">js</font>
程式碼免去了命名衝突等一系列開發難題。
<font face="新宋体">Node</font>
最大的特點就是採用了非同步式<font face="新宋体">I/O</font>
與事件驅動的架構設計。 <font face="新宋体">Node.js</font>
是一個讓js運作在瀏覽器外的平台。其最初目標是實現事件驅動,非阻塞<font face="新宋体">I/O</font>
的web伺服器
<font face="新宋体">Node.js</font>
只是一個 <font face="新宋体">JavaScript</font>
的運作環境(或一組函式庫), 為標準 <font face="新宋体">js</font>
補充了有關非同步 IO, 即讀寫網路和檔案的功能。
一個函式庫嘛,無非是調音 API 什麼的,除了略反人類的事件回呼之外,和其他後端語言(PHP, Python)也差不了多少。
<font face="新宋体">Node.js</font>
使用的是單線程模式,每一個線程完成一個功能,一個進程可以有多個線程,對於所有的I/O都採用非同步式的請求方式。每個非同步式I/O請求完成後都會推送到事件佇列,等待程式進程進行處理。
總之,<font face="新宋体">node</font>
的核心思想就是:非阻塞,單執行緒與事件驅動。 (同步對應的是阻塞,非同步對應的是非阻塞)
<font face="新宋体">Node.JS</font>
架構示意圖
單線程
<font face="新宋体">javascript</font>
語言的執行環境是"單執行緒"(single thread)。
所謂"單線程",就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。
這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是只要有一個任務耗時很長,後面的任務都必須排隊等著,會拖延整個程式的執行。常見的瀏覽器無 回應(假死),往往就是因為某一段<font face="新宋体">Javascript</font>
程式碼長時間運行(例如死循環),導致整個頁面卡在這個地方,其他任務無法執行。
大部分 Web 應用的瓶頸都在 <font face="新宋体">I/O</font>
, 即讀寫磁碟,讀寫網絡,讀寫資料庫。用怎樣的策略等待這段時間,就成了改善效能的關鍵點
同步與非同步
為了解決這個問題,<font face="新宋体">Javascript</font>
語言將任務的執行模式分成兩種:同步(Synchronous)和非同步(Asynchronous)。
"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,然後再執行,程式的執行順序與任務的排列順序是一致的、同步的;"非同步模式"則完全不同,每一個任務有一個或多個回調函數(<font face="新宋体">callback</font>
),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、非同步的。
"非同步模式"非常重要。在瀏覽器端,耗時很長的操作都應該非同步執行,避免瀏覽器失去回應,最好的例子就是Ajax操作。在伺服器端,"非同步模式"甚至是唯一的模式,因為執行環境是單線程的,如果允許同步執行所有<font face="新宋体">http</font>
請求,伺服器效能會急劇下降,很快就會失去回應。
進程與執行緒
mac系統中的行程與執行緒
從圖中我們可以看出,一個進程可以包含多個線程,進程就好比工程裡的車間,線程就是這個車間的工人,在引入線程的操作系統中,通常都是把進程作為分配資源的基本單位,而把執行緒當作獨立運作和獨立調度的基本單位。由於執行緒比進程更小,基本上不擁有系統資源,故對它的調度所付出的開銷就會小得多,能更有效率的提高系統內多個程式間並發執行的程度。
區別
線程和進程的區別在於,子進程和父進程有不同的程式碼和資料空間,而多個執行緒則共享資料空間,每個執行緒都有自己的執行堆疊和程式計數器為其執行上下文。多執行緒主要是為了節省CPU時間,發揮利用,根據具體情況而定。在執行緒的運行中需要使用電腦的記憶體資源和CPU。
模組和套件模組
模組:一個實現某些特定功能的文件,以實現模組化編程。透過require(模組名)引入模組.
—模組中的功能(如:變量,函數)透過賦給<font face="新宋体">exports</font>
物件的某個屬性提供給呼叫者使用。
如何使用模組?
在Node中使用模組是非常方便的,在 <font face="新宋体">JavaScript</font>
程式碼中可以直接使用全域函數 <font face="新宋体">require()</font>
來載入一個模組。例如,我們可以使用<font face="新宋体">require("http")</font>
來載入<font face="新宋体">node</font>
中自帶的http伺服器模組,
包
套件:套件是一個資料夾,它將模組封裝起來,用於發布、更新、依賴管理和版本控制。透過package.json來描述套件的資訊:入口文件,依賴的外部套件等等。透過<font face="新宋体">npm install</font>
指令來安裝包,並透過<font face="新宋体">require</font>
使用包。
非同步式 I/O 與事件驅動
<font face="新宋体">Node.js</font>
的非同步機制是基於事件的,每一個<font face="新宋体">I/O</font>
就是一次請求,所有的磁碟<font face="新宋体">I/O</font>
、網路通訊、資料庫查詢都以非阻塞的方式請求,傳回的結果由事件循環來處理。如下圖:
<font face="新宋体">Node.js</font>
進程在同一時刻只會處理一個事件,完成後立即進入事件循環檢查並處理後面的事件。這樣做的好處是,CPU 和內存在同一時間集中處理一件事,同時盡可能讓耗時的 I/O 操作並行執行
開始node程式設計
在這裡,我推薦大家使用<font face="新宋体">webstorm</font>
進行<font face="新宋体">node.js</font>
的開發,方便又快捷,比起cmd,或者Mac下的終端都好用太多了。
至於node的安裝大家就自行百度吧,這裡就不贅述了,看下<font face="新宋体">webstorm</font>
下的node程式介面吧:
我們只要在寫好的node程式碼介面按滑鼠右鍵,然後點選Run就行啦,方便又快速吧
下面是node的輸出介面:
在<font face="新宋体">Mac</font>
系統下進行web開發,我推薦大家使用的三款工具是:coda2,webstorm和Sublime text3這些是目前我已經的最好的開發工具了,大家不妨試試哪個更符合自己的口味。
在<font face="新宋体">webstorm</font>
進行node開發需要先配置一定的文件,大家就自行百度吧,因為我的<font face="新宋体">webstorm</font>
已經配置好了,所以沒法截圖給大家看步驟了,大概步驟是,在mac系統下方是先點選上方欄的<font face="新宋体">webstorm</font>
,再點選<font face="新宋体">perference</font>
,再點選<font face="新宋体">Node.js and NPM</font>
,然後右邊點選configure配置,最後大概會是下面這個樣子:
<font face="新宋体">windows</font>
系統下和這個流程步驟大概相似啊,我使用的版本是8.0.4的。
全域變數
在js程式設計中,我們最好為每個變數新增上var關鍵字,以免污染全域命名空間,提高程式碼的耦合風險。
console
<font face="新宋体">console</font>
用於向標準輸出流<font face="新宋体">standout</font>
(stdout)和標準錯誤流(stderr)輸出字元。
<font face="新宋体">console.log()</font>
向標準輸出流列印字元並以換行符結束,其接受多個參數,將以類似C語言的<font face="新宋体">printf()</font>
格式輸出
<code>console.log(__dirname)输出文件目录</code>
計算程式碼運行時間
<code> console.time(label) console.timeEnd(label)</code>
我們只需在開始和結束那裡給同樣一個標籤即可,中間放你想要計算執行時間的任何程式碼。
<font face="新宋体">__filename</font>
和<font face="新宋体">__dirname</font>
<code> console.log(__filename);// /Users/hwax/Desktop/My Project/avalon/hello.js console.log(__dirname);// /Users/hwax/Desktop/My Project/avalon</code>