首先,創建個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()是用來導入模塊的,一般直接把 require() 方法的返回值賦值給一個變量,在 JavaScript 代碼中直接使用此變量即可 。require("http") 就是加載系統預置的 http 模塊
b. http.createServer 是模塊的方法,目的就是創建並返回一個新的web server對象,並且給服務綁定一個回調,用以處理請求。
c. 通過 http.listen() 方法就可以讓該 HTTP 服務器在特定端口監聽。
d. console.log就不用多說了,瞭解firebug的都應該知道,Node實現了這個方法。
注: 想了解具體細節請查看文檔 cnodejs.org/cman/all.html#http.createServer
接着運行Node服務器,執行hello.js代碼,成功啓動會看見console.log()中的文本。有圖有真相:
npm的下載和使用
除Node本身提供的API外,現在有不少第三方模塊可極大的提高開發效率,npm就是Node的軟件包管理器,可以用它安裝所需軟件包併發布自己爲nodejs寫的軟件包。官網地址:npmjs.org
安裝只需要在終端寫入一行代碼:
curl http://npmjs.org/install.sh | sh
npm安裝node擴展包同樣是一行代碼:
npm install <包名> //例:npm install express
注:如果安裝模塊的過程中報域名錯誤的話,請清空緩存 >npm cache clean 或重啓計算機即可。
理解Node的模塊概念
在Node中,不同的功能組件被劃分成不同的模塊。應用可以根據自己的需要來選擇使用合適的模塊。每個模塊都會暴露一些公共的方法或屬性。模塊的使用者直接使用這些方法或屬性即可,對於內部的實現細節就可以不用瞭解。除了Node本身提供的API外,開發人員也可以利用這個機制來將應用拆分成多個模塊,以提高代碼的可複用性。
1.如何使用模塊?
在Node中使用模塊是非常方便的,在 JavaScript 代碼中可以直接使用全局函數 require() 來加載一個模塊。
在剛剛”Hello World"的例子中,require("http") 可以加載系統預置的 http 模塊;模塊名稱以 "./" 開始的,如 require("./myModule.js") 用來加載與當前 JavaScript 文件同一目錄下的 myModule.js 模塊。
2.自己如何開發模塊?
剛剛介紹使用require()導入模塊的時候,模塊名稱以 "./" 開始的這種,就是自己開發的模塊文件。需要注意的就是JS文件的系統路徑。
代碼中封裝了模塊的內部處理邏輯,一個模塊一般都會暴露一些公開的方法或屬性給其他的人使用。模塊的內部代碼需要把這些方法或屬性給暴露出來。
3.來一套簡單的例子。先創建一個模塊文件如myModule.js,就一行代碼
console.log('Hi Darren.')
然後創建一個test.js文件,導入這個JS文件,執行node看到結果
現在Node社區中已有不少第三方的模塊,希望能有更多人通過學習Node,加入到這個大家庭中,爲Node社區來添磚加瓦。先謝謝之,咱們繼續。
4.來一個深點的例子。這個例子中將會針對 私有和共有 進行介紹。先創建一個myModule.js,代碼如下:
var name = "Darren"; this.location = "Beijing"; this.showLog = function(){ console.log('Hi Darren.') };
代碼中出現了三種類型,分別是: 私用屬性,共有屬性和共有方法,再創建一個test.js,執行Node
結果高亮的地方很清楚的告訴我們,私有方法我們在模塊以外是取不到的,所以是undefined。共有屬性和共有方法的聲明需要在前面加上 this 關鍵字。
Node能做什麼和它的優勢
Node核心思想: 1.非阻塞; 2.單線程; 3.事件驅動。
在目前的web應用中,客戶端和服務器端之間有些交互可以認爲是基於事件的,那麼AJAX就是頁面及時響應的關鍵。每次發送一個請求時(不管請求的數據多麼小),都會在網絡裏走一個來回。服務器必須針對這個請求作出響應,通常是開闢一個新的進程。那麼越多用戶訪問這個頁面,所發起的請求個數就會越來越多,就會出現內存溢出、邏輯交錯帶來的衝突、網絡癱瘓、系統崩潰這些問題。
Node的目標是提供一種構建可伸縮的網絡應用的方案,在hello world例子中,服務器可以同時處理很多客戶端連接。
Node和操作系統有一種約定,如果創建了新的鏈接,操作系統就將通知Node,然後進入休眠。如果有人創建了新的鏈接,那麼它(Node)執行一個回調,每一個鏈接只佔用了非常小的(內存)堆棧開銷。
舉一個簡單的異步調用的例子,把test.js和myMydule.js準備好了,^_^。把以下代碼拷貝到test.js中並執行:
var fs = require('fs'); fs.readFile('./myModule.js', function (err, data) { if (err) throw err; console.log('successfully'); }); console.log('async');
所謂的異步,大家應該都能想得到運行時會先打先顯示"async",再顯示"successfully"。
Node是無阻塞的,新請求到達服務器時,不需要爲這個請求單獨作什麼事情。Node僅僅是在那裏等待請求的發生,有請求就處理請求。
Node更擅長處理體積小的請求以及基於事件的I/O。
Node不僅僅是做一個Web服務的框架,它可以做更多,比如它可以做Socket服務,可以做比方說基於文件的,然後基於像一些比方說可以有子進程,然後內部的,它是一個很完整的事件機制,包括一些異步非注射的解決方案,而不僅僅侷限在網絡一層。同時它可能,即使作爲一個Web服務來說,它也提供了更多可以深入這個服務內核、核心的一些功能,比方說Node使用的Http Agent,這塊就是它可以更深入這個服務內核來去做一些功能。
Node事件流概念
因爲Node 採用的是事件驅動的模式,其中的很多模塊都會產生各種不同的事件,可由模塊來添加事件處理方法,所有能夠產生事件的對象都是事件模塊中的 EventEmitter 類的實例。代碼是全世界通用的語言,所以我們還是用代碼說話:
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模塊並把返回值賦給了一個變量
2. new events.EventEmitter()這句創建了一個事件觸發器,也就是所謂的事件模塊中的 EventEmitter 類的實例
3. on(event, listener)用來爲某個事件 event 添加事件處理方法監聽器
4. emit(event, [arg1], [arg2], [...]) 方法用來產生事件。以提供的參數作爲監聽器函數的參數,順序執行監聽器列表中的每個監聽器函數。
EventEmitter 類中的方法都與事件的產生和處理相關:
1. addListener(event, listener) 和 on(event, listener) 這兩個方法都是將一個監聽器添加到指定事件的監聽器數組的末尾
2. once(event, listener) 這個方法爲事件爲添加一次性的監聽器。該監聽器在事件第一次觸發時執行,過後將被移除
3. removeListener(event, listener) 該方法用來將監聽器從指定事件的監聽器數組中移除出去
4. emit(event, [arg1], [arg2], [...]) 剛剛提到過了。
在Node中,存在各式各樣不同的數據流,Stream(流)是一個由不同對象實現的抽象接口。例如請求HTTP服務器的request是一個流,類似於stdout(標準輸出);包括文件系統、HTTP 請求和響應、以及 TCP/UDP 連接等。流可以是可讀的,可寫的,或者既可讀又可寫。所有流都是EventEmitter的實例,因此可以產生各種不同的事件。
可讀流主要會產生以下事件:
- data 當讀取到流中的數據時,此事件被觸發
- end 當流中沒有數據可讀時,此事件被觸發
- error 當讀取數據出現錯誤時,此事件被觸發
- close 當流被關閉時,,此事件被觸發,可是並不是所有流都會觸發這個事件。(例如,一個連接進入的HTTP request流就不會觸發'close'事件。)
還有一種比較特殊的 fd 事件,當在流中接收到一個文件描述符時觸發此事件。只有UNIX流支持這個功能,其他類型的流均不會觸發此事件。
相關詳細文檔:http://cnodejs.org/cman/all.html#events_
強大的File System 文件系統模塊
Node 中的 fs 模塊用來對本地文件系統進行操作。文件的I/O是由標準POSIX函數封裝而成。需要使用require('fs')訪問這個模塊。所有的方法都提供了異步和同步兩種方式。
fs 模塊中提供的方法可以用來執行基本的文件操作,包括讀、寫、重命名、創建和刪除目錄以及獲取文件元數據等。每個操作文件的方法都有同步和異步兩個版本。
異步操作的版本都會使用一個回調方法作爲最後一個參數。當操作完成的時候,該回調方法會被調用。而回調方法的第一個參數總是保留爲操作時可能出現的異常。如果操作正確成功,則第一個參數的值是 null 或 undefined 。
同步操作的版本的方法名稱則是在對應的異步方法之後加上一個 Sync 作爲後綴。比如異步的 rename() 方法的同步版本是 renameSync() 。下面列出來了 fs 模塊中的一些常用方法,都只介紹異步操作的版本。
test.js和myModule.js文件準備好了木?把下面這段代碼copy到test.js中執行一次
var fs = require('fs'); fs.unlink('./myModule.js', function (err) { if (err) throw err; console.log('successfully deleted myModule.js'); });
如果沒有報error,那麼myModule.js就被刪除了,就是這麼簡單
這只是一個簡單的例子,感興趣的話自己去多多嘗試,實踐出真理。由於篇幅原因就不多舉例了。^_^
推薦學習網站:https://cnodejs.org/getstart
http://nqdeng.github.io/7-days-nodejs/#1.1