node.js入門教程
Node是個(gè)啥?
寫個(gè)東西還是盡量面面俱到吧,所以有關(guān)基本概念的東西我也從網(wǎng)上選擇性的拿了些下來,有些地方針對(duì)自己的理解有所改動(dòng),對(duì)這些概念性的東西有過了解的可選擇跳過這段。
1.Node 是一個(gè)服務(wù)器端 JavaScript 解釋器,可是真的以為JavaScript不錯(cuò)的同學(xué)學(xué)習(xí)Node就能輕松拿下,那么你就錯(cuò)了,總結(jié):水深不深我還不知道,不過確實(shí)不淺。
2.Node 的目標(biāo)是幫助程序員構(gòu)建高度可伸縮的應(yīng)用程序,編寫能夠處理數(shù)萬條同時(shí)連接到一個(gè)物理機(jī)的連接代碼。處理高并發(fā)和異步I/O是Node受到開發(fā)人員的關(guān)注的原因之一。
3.Node 本身運(yùn)行Google V8 JavaScript引擎,所以速度和性能非常好,看chrome就知道,而且Node對(duì)其封裝的同時(shí)還改進(jìn)了其處理二進(jìn)制數(shù)據(jù)的能力。因此,Node不僅僅簡單的使用了V8,還對(duì)其進(jìn)行了優(yōu)化,使其在各種環(huán)境下更加給力。(什么是V8 JavaScript 引擎?請(qǐng)“百度知道”)
4.第三方的擴(kuò)展和模塊在Node的使用中起到重要的作用。下面也會(huì)介紹下載npm,npm就是模塊的管理工具,用它安裝各種 Node 的軟件包(如express,redis等)并發(fā)布自己為Node寫的軟件包 。
安裝Node
在這簡單說說在window7和linux兩種環(huán)境下安裝Node。安裝的時(shí)候一定要注意Python的版本,多次因?yàn)镻ython版本的問題安裝失敗,建議2.6+的版本,低版本會(huì)出現(xiàn)Node安裝錯(cuò)誤,查詢Python版本可在終端中輸入:pyhton -v
1.先介紹linux下的安裝吧,Node在Linux環(huán)境下的安裝和使用都非常方便,建議在Linux下運(yùn)行Node,^_^...我使用的是Ubuntu11.04
a.安裝依賴包:50-100kb/s大概每個(gè)包一分鐘就能下載安裝完成
sudo apt-get install g++ curl libssl-dev apache2-utils
sudo apt-get install git-core
b.在終端一步步運(yùn)行一下命令:
git clone git://github.com/joyent/node.git
cd node
./configure
make
sudo make install
安裝順利的話到這一步Node就算安裝成功了,2M的網(wǎng)絡(luò)用了共計(jì)12分鐘。
注:如果不用git下載也可以直接下載源碼,不過這樣下載安裝需要注意Node版本問題。使用git下載安裝是最方便的,所以推薦之。
2.在Windows下使用Cygwin安裝Node,這個(gè)方式不太推薦,因?yàn)檎娴男枰^長時(shí)間和較好的人品。我的系統(tǒng)是 win7旗艦版
Cygwin是一個(gè)在windows平臺(tái)上運(yùn)行的unix模擬環(huán)境,下載地址:http://cygwin.com/setup.exe。
下載好Cygwin后開始安裝,步驟:
a.選擇下載的來源 - Install from Internet
b.選擇下載安裝的根目錄
c.選擇下載文件所存放的目錄
d.選擇連接的方式
e.選擇下載的網(wǎng)站 - http://mirrors.163.com/cygwin
f.麻煩就麻煩在這步,考驗(yàn)人品的時(shí)候到了。需要的下載安裝時(shí)間不確定,反正需要比較長的時(shí)間(超過20分鐘),偶爾會(huì)出現(xiàn)安裝失敗的情況。單擊一下各個(gè)程序包前面的旋轉(zhuǎn)箭頭圖標(biāo)選擇你想要的版本,選中時(shí)會(huì)出現(xiàn)了"x"號(hào)表示已經(jīng)選中了該程序包。選擇需要下載的程序包:
Devel包:
gcc-g++: C++ compiler
gcc-mingw-g++: Mingw32 support headers and libraries for GCC C++
gcc4-g++: G++ subpackage
git: Fast Version Control System – core files
make: The GNU version of the ‘make' utility
openssl-devel: The OpenSSL development environment
pkg-config: A utility used to retrieve information about installed libraries
zlib-devel: The zlib compression/decompression library (development)
Editor包:vim: Vi IMproved – enhanced vi editor
Python包:把Default切換成install狀態(tài)即可
Web包:
wget: Utility to retrieve files from the WWW via HTTP and FTP
curl: Multi-protocol file transfer command-line tool
上個(gè)截圖,以下載zlib-devel為例:

上幾步走完才算把環(huán)境搭建完成,可是現(xiàn)在還沒有到安裝Node,還需要在Cywgin的ASH模式下執(zhí)行rebaseall,步驟如下:
a. cmd命令行
b. 進(jìn)入cygwin安裝目錄下的bin子目錄
c. 運(yùn)行ash進(jìn)入shell模式
d. ./rebaseall -v
e. 沒有錯(cuò)誤就關(guān)閉命令行窗口
好了,現(xiàn)在到下載安裝Node了,啟動(dòng)Cygwin.exe后輸入:
$ wget http://nodejs.org/dist/node-v0.4.12.tar.gz
$ tar xf node-v0.4.12.tar.gz
$ cd node-v0.4.12
$ ./configure
$ make
$ make install
3.直接下載node.exe文件
直接去nodejs.org下載,聽說有不太穩(wěn)定的問題,不過你假如只是想先在windows下了解Node,個(gè)人感覺這個(gè)方法比你裝個(gè)Cygwin好很多。
注:原本不太想寫安裝Node這段,可是為了這篇文章的全面性還是寫了,沒想到一寫就是那么長一段了...茶幾了
“Hello World” - 為什么每次見到這句心情都會(huì)小激動(dòng),不解...
首先,創(chuàng)建個(gè)hello.js的文件,在文件中copy如下代碼:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
代碼邏輯:
a. 全局方法require()是用來導(dǎo)入模塊的,一般直接把 require() 方法的返回值賦值給一個(gè)變量,在 JavaScript 代碼中直接使用此變量即可 。require("http") 就是加載系統(tǒng)預(yù)置的 http 模塊
b. http.createServer 是模塊的方法,目的就是創(chuàng)建并返回一個(gè)新的web server對(duì)象,并且給服務(wù)綁定一個(gè)回調(diào),用以處理請(qǐng)求。
c. 通過 http.listen() 方法就可以讓該 HTTP 服務(wù)器在特定端口監(jiān)聽。
d. console.log就不用多說了,了解firebug的都應(yīng)該知道,Node實(shí)現(xiàn)了這個(gè)方法。
注: 想了解具體細(xì)節(jié)請(qǐng)查看文檔 cnodejs.org/cman/all.html#http.createServer
接著運(yùn)行Node服務(wù)器,執(zhí)行hello.js代碼,成功啟動(dòng)會(huì)看見console.log()中的文本。有圖有真相:
npm的下載和使用
除Node本身提供的API外,現(xiàn)在有不少第三方模塊可極大的提高開發(fā)效率,npm就是Node的軟件包管理器,可以用它安裝所需軟件包并發(fā)布自己為nodejs寫的軟件包。官網(wǎng)地址:npmjs.org
安裝只需要在終端寫入一行代碼:
curl http://npmjs.org/install.sh | sh
npm安裝node擴(kuò)展包同樣是一行代碼:
npm install <包名> //例:npm install express
注:如果安裝模塊的過程中報(bào)域名錯(cuò)誤的話,請(qǐng)清空緩存 >npm cache clean 或重啟計(jì)算機(jī)即可。
理解Node的模塊概念
在Node中,不同的功能組件被劃分成不同的模塊。應(yīng)用可以根據(jù)自己的需要來選擇使用合適的模塊。每個(gè)模塊都會(huì)暴露一些公共的方法或?qū)傩?。模塊的使用者直接使用這些方法或?qū)傩约纯桑瑢?duì)于內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)就可以不用了解。除了Node本身提供的API外,開發(fā)人員也可以利用這個(gè)機(jī)制來將應(yīng)用拆分成多個(gè)模塊,以提高代碼的可復(fù)用性。
1.如何使用模塊?
在Node中使用模塊是非常方便的,在 JavaScript 代碼中可以直接使用全局函數(shù) require() 來加載一個(gè)模塊。
在剛剛”Hello World"的例子中,require("http") 可以加載系統(tǒng)預(yù)置的 http 模塊;模塊名稱以 "./" 開始的,如 require("./myModule.js") 用來加載與當(dāng)前 JavaScript 文件同一目錄下的 myModule.js 模塊。
2.自己如何開發(fā)模塊?
剛剛介紹使用require()導(dǎo)入模塊的時(shí)候,模塊名稱以 "./" 開始的這種,就是自己開發(fā)的模塊文件。需要注意的就是JS文件的系統(tǒng)路徑。
代碼中封裝了模塊的內(nèi)部處理邏輯,一個(gè)模塊一般都會(huì)暴露一些公開的方法或?qū)傩越o其他的人使用。模塊的內(nèi)部代碼需要把這些方法或?qū)傩越o暴露出來。
3.來一套簡單的例子。先創(chuàng)建一個(gè)模塊文件如myModule.js,就一行代碼
console.log('Hi Darren.')
然后創(chuàng)建一個(gè)test.js文件,導(dǎo)入這個(gè)JS文件,執(zhí)行node看到結(jié)果
現(xiàn)在Node社區(qū)中已有不少第三方的模塊,希望能有更多人通過學(xué)習(xí)Node,加入到這個(gè)大家庭中,為Node社區(qū)來添磚加瓦。先謝謝之,咱們繼續(xù)?! ?/P>
4.來一個(gè)深點(diǎn)的例子。這個(gè)例子中將會(huì)針對(duì) 私有和共有 進(jìn)行介紹。先創(chuàng)建一個(gè)myModule.js,代碼如下:
var name = "Darren";
this.location = "Beijing";
this.showLog = function(){
console.log('Hi Darren.')
};
代碼中出現(xiàn)了三種類型,分別是: 私用屬性,共有屬性和共有方法,再創(chuàng)建一個(gè)test.js,執(zhí)行Node

結(jié)果高亮的地方很清楚的告訴我們,私有方法我們?cè)谀K以外是取不到的,所以是undefined。共有屬性和共有方法的聲明需要在前面加上 this 關(guān)鍵字。
Node能做什么和它的優(yōu)勢
Node核心思想: 1.非阻塞; 2.單線程; 3.事件驅(qū)動(dòng)。
在目前的web應(yīng)用中,客戶端和服務(wù)器端之間有些交互可以認(rèn)為是基于事件的,那么AJAX就是頁面及時(shí)響應(yīng)的關(guān)鍵。每次發(fā)送一個(gè)請(qǐng)求時(shí)(不管請(qǐng)求的數(shù)據(jù)多么小),都會(huì)在網(wǎng)絡(luò)里走一個(gè)來回。服務(wù)器必須針對(duì)這個(gè)請(qǐng)求作出響應(yīng),通常是開辟一個(gè)新的進(jìn)程。那么越多用戶訪問這個(gè)頁面,所發(fā)起的請(qǐng)求個(gè)數(shù)就會(huì)越來越多,就會(huì)出現(xiàn)內(nèi)存溢出、邏輯交錯(cuò)帶來的沖突、網(wǎng)絡(luò)癱瘓、系統(tǒng)崩潰這些問題。
Node的目標(biāo)是提供一種構(gòu)建可伸縮的網(wǎng)絡(luò)應(yīng)用的方案,在hello world例子中,服務(wù)器可以同時(shí)處理很多客戶端連接。
Node和操作系統(tǒng)有一種約定,如果創(chuàng)建了新的鏈接,操作系統(tǒng)就將通知Node,然后進(jìn)入休眠。如果有人創(chuàng)建了新的鏈接,那么它(Node)執(zhí)行一個(gè)回調(diào),每一個(gè)鏈接只占用了非常小的(內(nèi)存)堆棧開銷?! ?
舉一個(gè)簡單的異步調(diào)用的例子,把test.js和myMydule.js準(zhǔn)備好了,^_^。把以下代碼拷貝到test.js中并執(zhí)行:
var fs = require('fs');
fs.readFile('./myModule.js', function (err, data) {
if (err) throw err;
console.log('successfully');
});
console.log('async');

所謂的異步,大家應(yīng)該都能想得到運(yùn)行時(shí)會(huì)先打先顯示"async",再顯示"successfully"。
Node是無阻塞的,新請(qǐng)求到達(dá)服務(wù)器時(shí),不需要為這個(gè)請(qǐng)求單獨(dú)作什么事情。Node僅僅是在那里等待請(qǐng)求的發(fā)生,有請(qǐng)求就處理請(qǐng)求。
Node更擅長處理體積小的請(qǐng)求以及基于事件的I/O。
Node不僅僅是做一個(gè)Web服務(wù)的框架,它可以做更多,比如它可以做Socket服務(wù),可以做比方說基于文件的,然后基于像一些比方說可以有子進(jìn)程,然后內(nèi)部的,它是一個(gè)很完整的事件機(jī)制,包括一些異步非注射的解決方案,而不僅僅局限在網(wǎng)絡(luò)一層。同時(shí)它可能,即使作為一個(gè)Web服務(wù)來說,它也提供了更多可以深入這個(gè)服務(wù)內(nèi)核、核心的一些功能,比方說Node使用的Http Agent,這塊就是它可以更深入這個(gè)服務(wù)內(nèi)核來去做一些功能。
Node事件流概念
因?yàn)镹ode 采用的是事件驅(qū)動(dòng)的模式,其中的很多模塊都會(huì)產(chǎn)生各種不同的事件,可由模塊來添加事件處理方法,所有能夠產(chǎn)生事件的對(duì)象都是事件模塊中的 EventEmitter 類的實(shí)例。代碼是全世界通用的語言,所以我們還是用代碼說話:
var events = require("events");
var emitter = new events.EventEmitter();
emitter.on("myEvent", function(msg) {
console.log(msg);
});
emitter.emit("myEvent", "Hello World.");
簡單的分析這段:
1. 使用require()方法添加了events模塊并把返回值賦給了一個(gè)變量
2. new events.EventEmitter()這句創(chuàng)建了一個(gè)事件觸發(fā)器,也就是所謂的事件模塊中的 EventEmitter 類的實(shí)例
3. on(event, listener)用來為某個(gè)事件 event 添加事件處理方法監(jiān)聽器
4. emit(event, [arg1], [arg2], [...]) 方法用來產(chǎn)生事件。以提供的參數(shù)作為監(jiān)聽器函數(shù)的參數(shù),順序執(zhí)行監(jiān)聽器列表中的每個(gè)監(jiān)聽器函數(shù)。
EventEmitter 類中的方法都與事件的產(chǎn)生和處理相關(guān):
1. addListener(event, listener) 和 on(event, listener) 這兩個(gè)方法都是將一個(gè)監(jiān)聽器添加到指定事件的監(jiān)聽器數(shù)組的末尾
2. once(event, listener) 這個(gè)方法為事件為添加一次性的監(jiān)聽器。該監(jiān)聽器在事件第一次觸發(fā)時(shí)執(zhí)行,過后將被移除
3. removeListener(event, listener) 該方法用來將監(jiān)聽器從指定事件的監(jiān)聽器數(shù)組中移除出去
4. emit(event, [arg1], [arg2], [...]) 剛剛提到過了。
在Node中,存在各式各樣不同的數(shù)據(jù)流,Stream(流)是一個(gè)由不同對(duì)象實(shí)現(xiàn)的抽象接口。例如請(qǐng)求HTTP服務(wù)器的request是一個(gè)流,類似于stdout(標(biāo)準(zhǔn)輸出);包括文件系統(tǒng)、HTTP 請(qǐng)求和響應(yīng)、以及 TCP/UDP 連接等。流可以是可讀的,可寫的,或者既可讀又可寫。所有流都是EventEmitter的實(shí)例,因此可以產(chǎn)生各種不同的事件。
可讀流主要會(huì)產(chǎn)生以下事件:
1.data 當(dāng)讀取到流中的數(shù)據(jù)時(shí),此事件被觸發(fā)
2.end 當(dāng)流中沒有數(shù)據(jù)可讀時(shí),此事件被觸發(fā)
3.error 當(dāng)讀取數(shù)據(jù)出現(xiàn)錯(cuò)誤時(shí),此事件被觸發(fā)
4.close 當(dāng)流被關(guān)閉時(shí),,此事件被觸發(fā),可是并不是所有流都會(huì)觸發(fā)這個(gè)事件。(例如,一個(gè)連接進(jìn)入的HTTP request流就不會(huì)觸發(fā)'close'事件。)
還有一種比較特殊的 fd 事件,當(dāng)在流中接收到一個(gè)文件描述符時(shí)觸發(fā)此事件。只有UNIX流支持這個(gè)功能,其他類型的流均不會(huì)觸發(fā)此事件。
相關(guān)詳細(xì)文檔:http://cnodejs.org/cman/all.html#events_
強(qiáng)大的File System 文件系統(tǒng)模塊
Node 中的 fs 模塊用來對(duì)本地文件系統(tǒng)進(jìn)行操作。文件的I/O是由標(biāo)準(zhǔn)POSIX函數(shù)封裝而成。需要使用require('fs')訪問這個(gè)模塊。所有的方法都提供了異步和同步兩種方式。
fs 模塊中提供的方法可以用來執(zhí)行基本的文件操作,包括讀、寫、重命名、創(chuàng)建和刪除目錄以及獲取文件元數(shù)據(jù)等。每個(gè)操作文件的方法都有同步和異步兩個(gè)版本。
異步操作的版本都會(huì)使用一個(gè)回調(diào)方法作為最后一個(gè)參數(shù)。當(dāng)操作完成的時(shí)候,該回調(diào)方法會(huì)被調(diào)用。而回調(diào)方法的第一個(gè)參數(shù)總是保留為操作時(shí)可能出現(xiàn)的異常。如果操作正確成功,則第一個(gè)參數(shù)的值是 null 或 undefined 。
同步操作的版本的方法名稱則是在對(duì)應(yīng)的異步方法之后加上一個(gè) Sync 作為后綴。比如異步的 rename() 方法的同步版本是 renameSync() 。下面列出來了 fs 模塊中的一些常用方法,都只介紹異步操作的版本。
test.js和myModule.js文件準(zhǔn)備好了木?把下面這段代碼copy到test.js中執(zhí)行一次
fs.unlink('./myModule.js', function (err) {
if (err) throw err;
console.log('successfully deleted myModule.js');
});
如果沒有報(bào)error,那么myModule.js就被刪除了,就是這么簡單

這只是一個(gè)簡單的例子,感興趣的話自己去多多嘗試,實(shí)踐出真理。由于篇幅原因就不多舉例了。^_^
學(xué)習(xí)Node的總結(jié):
1.對(duì)于一個(gè)linux的命令和shell知識(shí)幾乎為零的我來說,這段時(shí)間又學(xué)到了不少關(guān)于linux知識(shí);vim真是一個(gè)強(qiáng)大的編輯器,不用鼠標(biāo)的感覺真的很好;而且有一點(diǎn)對(duì)我來說很重要,在linux下編程很cool,尤其是在團(tuán)隊(duì)中都是使用windows的,裝裝更健康^_^。
2.理解了服務(wù)端JavaScript的一個(gè)成功框架-Node,以及它的一些優(yōu)勢和使用的方式,這篇文章就是最好的總結(jié),當(dāng)然,這只會(huì)是一個(gè)開始。
一些想對(duì)大伙說的話:
1. 在這我得打擊一部分人的積極性。假如你對(duì)后臺(tái)技術(shù)不夠了解或者沒接觸過服務(wù)端語言,不知道I/O這些知識(shí),沒有后臺(tái)處理流程這種概念,那么......Node并不是一門適合入門的服務(wù)端技術(shù)。為什么這么說:
a.重點(diǎn)就是中文實(shí)例少,文章少,想系統(tǒng)的學(xué)習(xí)會(huì)比較麻煩,所以在使用過程中總有一種不成熟的感覺,當(dāng)然主要還是因?yàn)槲覍?duì)它不熟悉所造成的。國內(nèi)使用Node的公司確實(shí)不多,當(dāng)然國外還是有不少了,從cnodejs.org截了一個(gè)圖:
3.對(duì)于沒有進(jìn)入那么夢想的公司其實(shí)是有那么點(diǎn)遺憾,不過生活就應(yīng)該要這樣,有波折有起伏,這正是我需要并且期待的...那么新的生活還是要繼續(xù),做自己的舵手,把握好自己的方向,過去的就讓它過去吧。
b.對(duì)沒有經(jīng)驗(yàn)的朋友來說node其實(shí)并不好上手,從最簡單“Hello world”就可以看出來(各種運(yùn)行環(huán)境和安裝細(xì)節(jié)的了解都得費(fèi)點(diǎn)功夫),不要以jQuery庫為比較,所處理的事物不同,學(xué)習(xí)的成本也不同 - 所以不太建議作為新手入門的服務(wù)端技術(shù),如果想學(xué)習(xí)一門服務(wù)端語言PHP和Python都是不錯(cuò)的選擇,因?yàn)椋簳?例子多 框架多 上手簡單 容易理解 搭建方便...
c.以上都是我個(gè)人善意的建議,由于水平有限,請(qǐng)大家多多指教,希望嘴下留情。
2. 關(guān)于Node的書寫規(guī)范和具體技巧本人就不獻(xiàn)丑了,自己寫Node的代碼也不多,不過面向?qū)ο蟮木幊趟枷朐谀亩际呛檬沟摹?/P>
3. 希望這篇文章能對(duì)大家學(xué)習(xí)Node有用
相關(guān)文章
Node.js完整實(shí)現(xiàn)博客系統(tǒng)詳解
這篇文章主要介紹了Node.js完整實(shí)現(xiàn)一個(gè)博客系統(tǒng)的流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08nest.js,egg.js,midway,express,koa的區(qū)別小結(jié)
本文主要介紹了nest.js,egg.js,midway,express,koa的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Node.js開發(fā)教程之基于OnceIO框架實(shí)現(xiàn)文件上傳和驗(yàn)證功能
這篇文章主要介紹了Node.js開發(fā)教程之基于OnceIO框架實(shí)現(xiàn)文件上傳和驗(yàn)證的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11nodejs開發(fā)微信小程序?qū)崿F(xiàn)密碼加密
本文給大家分享的是在使用nodejs開發(fā)微信小程序的過程中,實(shí)現(xiàn)密碼加密的示例代碼,非常簡單,有需要的小伙伴可以參考下2017-07-07koa上傳excel文件并解析的實(shí)現(xiàn)方法
這篇文章主要介紹了koa上傳excel文件并解析的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08深入了解 Node的多進(jìn)程服務(wù)實(shí)現(xiàn)
本文主要介紹了Node的多進(jìn)程服務(wù)實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06