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