Node.js知識點詳解(一)基礎部分

模塊

Node.js 提供了exportsrequire 兩個對象,其中 exports 是模塊公開的接口,require 用於從外部獲取一個模塊的接口,即所獲取模塊的 exports 對象。
接下來咱們就來建立hello.js文件,代碼以下:javascript

exports.world = function() {
  console.log('Hello World');
}

在以上示例中,hello.js 經過 exports 對象把 world 做爲模塊的訪問接口,在 main.js 中經過 require('./hello') 加載這個模塊,而後就能夠直接訪 問main.jsexports 對象的成員函數了。html

require方法接受如下幾種參數的傳遞:前端

http、fs、path等,原生模塊。
./mod或../mod,相對路徑的文件模塊。
/pathtomodule/mod,絕對路徑的文件模塊。
mod,非原生模塊的文件模塊。

咱們以計算圓的周長和麪積的兩個方法爲例:java

var PI = Math.PI;
exports.area = function (r) {
    return PI*r*r;
};//exports 是對象,向外提供了area方法接口
 
exports.circumference = function (r) {
    return 2*PI*r;
};

以上保存爲circle.js,下方經過require調用模塊:node

var circle = require("./circle.js");//require經過引入模塊文件,找到exports對象提供的接口
console.log("The area of a circle of radius 4 is " + circle.area(4));

編寫稍大一點的程序時通常都會將代碼模塊化。在NodeJS中,通常將代碼合理拆分到不一樣的JS文件中,每個文件就是一個模塊,而文件路徑就是模塊名。mysql

在編寫每一個模塊時,都有require、exports、module三個預先定義好的變量可供使用。
模塊名可以使用相對路徑(以./開頭),或者是絕對路徑(以/或C:之類的盤符開頭)。另外,模塊名中的.js擴展名能夠省略。git

模塊化的優缺點:

a>優勢:
可維護性
1.靈活架構,焦點分離
2.方便模塊間組合、分解
3.方便單個模塊功能調試、升級
4.多人協做互不干擾
可測試性
1.可分單元測試

b>缺點:
性能損耗
1.系統分層,調用鏈會很長
2.模塊間通訊,模塊間發送消息會很耗性能

Node.js經常使用模塊和組件

包管理 Package Management: NPM 
 框架 Framework: ExpressJS 
 模板 Template: Jade 
 中間件 Middleware: Connect 
 WebSocket: Socket.io 
 數據庫 Database: Mongo DB (選了個本身喜歡的) 
 Mongoose (as a MongoDB ORM) 
 調錯 Debugging: Node Inspector 
 測試 Test: Mocha + should.js 
 控制無止境的內嵌回調 (Control the Callback flow): Async

Node.js能夠作什麼?

Web開發:Express + EJS + Mongoose/MySQL

express 是輕量靈活的Nodejs Web應用框架,它能夠快速地搭建網站。
Express框架創建在Nodejs內置的Http模塊上,並對Http模塊再包裝,從而實際Web請求處理的功能。

ejs是一個嵌入的Javascript模板引擎,經過編譯生成HTML的代碼。

mongoose 是MongoDB的對象模型工具,經過Mongoose框架,能夠進行訪問MongoDB的操做。

mysql 是鏈接MySQL數據庫的通訊API,能夠進行訪問MySQL的操做。

一般用Node.js作Web開發,須要3個框架配合使用,就像Java中的SSH。github

Web聊天室(IM):Express + Socket.io

socket.io一個是基於Nodejs架構體系的,支持websocket的協議用於時時通訊的一個軟件包。socket.io 給跨瀏覽器構建實時應用提供了完整的封裝,socket.io徹底由javascript實現。web

63918611gw1ehp0gqp2pkj20go0b40tf.jpg

Web爬蟲:Cheerio/Request

cheerio 是一個爲服務器特別定製的,快速、靈活、封裝jQuery核心功能工具包。Cheerio包括了 jQuery核心的子集,從jQuery庫中去除了全部DOM不一致性和瀏覽器不兼容的部分,揭示了它真正優雅的API。Cheerio工做在一個很是簡 單,一致的DOM模型之上,解析、操做、渲染都變得難以置信的高效。基礎的端到端的基準測試顯示Cheerio大約比JSDOM快八倍(8x)。 Cheerio封裝了@FB55兼容的htmlparser,幾乎可以解析任何的 HTML 和 XML document。sql

Web博客:Hexo

Hexo 是一個簡單地、輕量地、基於Node的一個靜態博客框架。經過Hexo咱們能夠快速建立本身的博客,僅須要幾條命令就能夠完成。

發佈時,Hexo能夠部署在本身的Node服務器上面,也能夠部署github上面。對於我的用戶來講,部署在github上好處頗多,不只能夠省 去服務器的成本,還能夠減小各類系統運維的麻煩事(系統管理、備份、網絡)。因此,基於github的我的站點,正在開始流行起來….

前端包管理平臺: bower.js

Bower 是 twitter 推出的一款包管理工具,基於nodejs的模塊化思想,把功能分散到各個模塊中,讓模塊和模塊之間存在聯繫,經過 Bower 來管理模塊間的這種聯繫。

單線程

javascript語言的執行環境是"單線程"(single thread)。
所謂"單線程",就是指一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。

這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是隻要有一個任務耗時很長,後面的任務都必須排隊等着,會拖延整個程序的執行。常見的瀏覽器無 響應(假死),每每就是由於某一段Javascript代碼長時間運行(好比死循環),致使整個頁面卡在這個地方,其餘任務沒法執行。

大部分 Web 應用的瓶頸都在 I/O, 即讀寫磁盤,讀寫網絡,讀寫數據庫。使用怎樣的策略等待這段時間,就成了改善性能的關鍵點

同步與異步

爲了解決這個問題,Javascript語言將任務的執行模式分紅兩種:同步(Synchronous)和異步(Asynchronous)。

"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,而後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則徹底不一樣, 每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執 行,因此程序的執行順序與任務的排列順序是不一致的、異步的。

"異步模式"很是重要。在瀏覽器端,耗時很長的操做都應該異步執行,避免瀏覽器失去響應,最好的例子就是Ajax操做。在服務器端,"異步模式"甚至是惟一的模式,由於執行環境是單線程的,若是容許同步執行全部http請求,服務器性能會急劇降低,很快就會失去響應。

進程與線程

mac系統中的進程與線程

mac系統中的進程與線程

從圖中咱們能夠看出,一個進程能夠包括多個線程,進程就比如工程裏的車間,線程就是這個車間的工人,在引入線程的操做系統中,一般都是把進程做爲分配資源的基本單位,而把線程做爲獨立運行和獨立調度的基本單位。因爲線程比進程更小,基本上不擁有系統資源,故對它的調度所付出的開銷就會小得多,能更高效的提升系統內多個程序間併發執行的程度。

區別

線程和進程的區別在於,子進程和父進程有不一樣的代碼和數據空間,而多個線程則共享數據空間,每一個線程有本身的執行堆棧和程序計數器爲其執行上下文。多線程主要是爲了節約CPU時間,發揮利用,根據具體狀況而定。線程的運行中須要使用計算機的內存資源和CPU。

圖片描述

模塊和包

模塊

模塊:一個實現某些特定功能的文件,以實現模塊化編程。經過require(模塊名)引入模塊.
—模塊中的功能(如:變量,函數)經過賦給exports對象的某個屬性提供給調用者使用。

模塊是可重用的代碼庫。好比用來與數據庫交互的模塊、支持web開發的模塊以及經過web套接字協助通訊的模塊

如何使用模塊?

在Node中使用模塊是很是方便的,在 JavaScript 代碼中能夠直接使用全局函數 require() 來加載一個模塊。例如,咱們可使用require("http")來加載node中自帶的http服務器模塊,

包是一個文件夾,它將模塊封裝起來,用於發佈、更新、依賴管理和版本控制。經過package.json來描述包的信息:入口文件,依賴的外部包等等。經過npm install命令來安裝包,並經過require使用包。

package.json

在開發Node.js應用程序的時候,一個一個模塊的安裝顯然很耗時,又或是忘了安裝某個模塊怎麼辦?npm容許開發人員使用package.json文件來指定在應用程序中要用的模塊,而且經過單個命令來安裝它們:

npm install

package.json文件僅包含以特定格式表示的項目信息。一個最小的package.json文件會是這樣:

{
    "name" : "example 1",
    "version": "0.0.2",
    "dependencies":{
       "underscore":"~1.2.1"
    }
}

使用package.json文件意味着咱們無需記憶應用程序會依賴於哪些模塊,其餘開發人員會發現,能夠很簡單地安裝你的應用程序

npm install <name>安裝nodejs的依賴包
npm install <name> -g  將包安裝到全局環境中
npm install <name> --save  安裝的同時,將信息寫入package.json中
npm init  會引導你建立一個package.json文件,包括名稱、版本、做者這些信息等
npm remove <name>移除
npm update <name>更新

Package.json的屬性

name - 包的名稱

version - 包的版本

description - 包的描述

homepage - 包主頁

author - 包的做者

contributors - 貢獻者到包的名字

dependencies - 依賴關係的列表。NPM自動安裝全部在這裏的包node_module文件夾中提到的依賴關係。

repository - 包的庫類型和URL

main - 包的入口點

keywords - 關鍵字

npm install module-name -save 自動把模塊和版本號添加到dependencies部分
npm install module-name -save-dve 自動把模塊和版本號添加到devdependencies部分

異步式 I/O 與事件驅動

Node.js 的異步機制是基於事件的,I/O 是輸入輸出的意思,指的是計算機和人或者數據處理系統之間的通訊。能夠將I/O 想成是數據在一次輸入和一次輸出之間的移動。

每個 I/O就是一次請求,全部的磁盤 I/O、網絡通訊、數據庫查詢都以非阻塞的方式請求,返回的結果由事件循環來處理。以下圖所示:

07225746-f18b435c77aa413599a790d1ceba1b9b.jpg

Node.js 進程在同一時刻只會處理一個事件,完成後當即進入事件循環檢查並處理後面的事件。這樣作的好處是,CPU 和內存在同一時間集中處理一件事,同時儘量讓耗時的 I/O 操做並行執行

07225745-77c1a9ced4e1430e8c56b201a7382c6e.png

開始node編程

在這裏,我推薦你們使用webstorm進行node.js的開發,方便又快捷,比起cmd,或者Mac下的終端都好用太多了。

至於node的安裝你們就自行百度吧,這裏就不贅述了,看下webstorm下的node編程界面吧:
咱們只須要在編寫好的node代碼界面按鼠標右鍵,而後點擊Run就行啦,方便又快捷吧

圖片描述

下面是node的輸出界面:

圖片描述

Mac系統下進行web開發,我推薦你們使用的三款工具是:coda2這些是目前我已經的最好的開發工具了,你們不妨試試哪一個更符合本身的口味。

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

__filename:開發期間,該行代碼所在的文件。
__dirname:開發期間,該行代碼所在的目錄。

path.join([path1],[path2],[...])

合併參數獲得一個標準化的路徑字符串

path.join('/foo', 'bar', 'baz/abc')
// returns
'/foo/bar/baz/abc'

運行hello world程序

首先在終端輸入:

trigkit4:~ trigkit4$ vi index.js

進入vim後輸入i,進入編輯模式,而後輸入:

var http = require('http');
http.createServer(function(req,res){
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end("Hello World\n");
}).listen(8124,"127.0.0.1");
console.log("Server running at http://127.0.0.1:8124/");

而後按ESC,退出編輯模式,輸入:w保存,再輸入:q退出

而後接着在終端輸入以下命令:

trigkit4:~ trigkit4$ node index

能夠看到終端輸出了:

Server running at http://127.0.0.1:8124/

而後打開瀏覽器,輸入地址便可看到輸出hello world

Node.js包目錄

通常一個Node.js的包的根目錄結構以下:

.gitignore —— 從git上忽略的文件清單
 .npmignore —— 不包括npm註冊庫中的文件清單
 LICENSE —— 包的受權文件
 README.md —— 以markdown格式編寫的readme文件
 bin —— 保存包可執行文件的文件夾
 doc —— 保存包文檔的文件夾
 examples —— 保存如何使用包的實例文件夾
 lib —— 保存包代碼的文件夾
 man —— 保存包的手冊頁的文件夾
 package.json —— 描述包的json文件
 src —— 保存C/C++源文件的文件夾
 deps —— 保存包所用到的依賴文件夾
 test —— 保存模塊測試的文件夾
 index.js —— 包的入口文件

 "scripts": {//「scripts」是一個由腳本命令組成的hash對象,他們在包不一樣的生命週期中被執行。key是生命週期事件,value是要運行的命令。
        "test": "node ./libuv/test.js"
      },
"main": "index.js",//包的入口文件,如不指定,則爲根目錄下的index.js
相關文章
相關標籤/搜索