成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Node.js 開發(fā)指南 讀書筆記

CocoaChina / 3120人閱讀

摘要:為指定事件注冊(cè)一個(gè)監(jiān)聽器,接受一個(gè)字符串和一個(gè)回調(diào)函數(shù)。發(fā)射事件,傳遞若干可選參數(shù)到事件監(jiān)聽器的參數(shù)表。為指定事件注冊(cè)一個(gè)單次監(jiān)聽器,即監(jiān)聽器最多只會(huì)觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽器。

1.Node.js 簡(jiǎn)介

Node.js 其實(shí)就是借助谷歌的 V8 引擎,將桌面端的 js 帶到了服務(wù)器端,它的出現(xiàn)我將其歸結(jié)為兩點(diǎn):

V8 引擎的出色;

js 異步 io 與事件驅(qū)動(dòng)給服務(wù)器帶來極高的 吞吐量/硬件性能 比例。

2.安裝和配置Node.js

安裝的話基本是分為 Windows 和 POSIX(為*unx 和 Mac等系統(tǒng)的統(tǒng)稱)。

2.1.在 Windows 上,很簡(jiǎn)單,訪問官網(wǎng),下載對(duì)應(yīng)的安裝包安裝即可。 2.2.在 POSIX 上安裝

大都可以從相應(yīng)的包管理器上進(jìn)行安裝(非大神不推薦用源碼,因?yàn)樵创a編譯涉及相關(guān)參數(shù))。
不過包管理器上的并非是最新的,還可能是很老舊的版本,所以需要我們?nèi)ス倬W(wǎng)下載編譯好的二進(jìn)制來進(jìn)行安裝.
關(guān)于安裝,我在我的其他文章中有說到,比較簡(jiǎn)單的.
在安裝的時(shí)候,會(huì)默認(rèn)自帶一個(gè) npm 包管理器,這個(gè) npm 上托管了幾乎所有的 node.js 程序包,你能夠通過它下載各種流行的基于 node.js 的軟件.

3.Node.js快速入門 3.1.Hello World

當(dāng)然,快速入門少不了 Hello World,Node.js其實(shí)和瀏覽器上的 javascript 差不太多,只是Node.js上增加了一些引用的方法以及結(jié)構(gòu),并且去除了 Dom 的操作(Node上并沒有Dom可以操作..),所以,你可以直接用以下語句打印出一句"Hello World":

console.log("Hello World");
3.2.建立一個(gè)Web Server

Node.js是一個(gè)服務(wù)器程序,當(dāng)然就要提供Web服務(wù),以下代碼能讓你建立起一個(gè)最基礎(chǔ)的Web服務(wù)器,因?yàn)樗鼘?duì)所有的請(qǐng)求都只返回同樣的頁面:

//app.js 
 
var http = require("http"); 
 
http.createServer(function(req, res) { 
  res.writeHead(200, {"Content-Type": "text/html"}); 
  res.write("

Node.js

"); res.end("

Hello World

"); }).listen(3000); console.log("HTTP server is listening at port 3000.");
3.3.異步IO

在js 中,最重要的部分之一就是它的異步編程,通過事件輪詢,在單線程上它能夠接受更多的請(qǐng)求并且將資源最大化利用.
比如像下面的讀取文件程序,在調(diào)用讀取函數(shù)后,程序會(huì)繼續(xù)往下運(yùn)行,等到讀取完成后,才會(huì)調(diào)用讀取函數(shù)所綁定的那個(gè)回調(diào)函數(shù):

//readfilesync.js 
 
var fs = require("fs"); 
var data = fs.readFileSync("file.txt", "utf-8"); 
console.log(data); 
console.log("end."); 
3.4.模塊和包 3.4.1.創(chuàng)建模塊

node的幾乎所有程序都是通過各種模塊以及包組合完成的.每個(gè)模塊或者包都有他特殊的功能以及特定的調(diào)用方法.
創(chuàng)建及加載模塊:

// 讓我們以一個(gè)例子來了解模塊。創(chuàng)建一個(gè) module.js 的文件,內(nèi)容是: 
//module.js 
 
var name; 
 
exports.setName = function(thyName) { 
  name = thyName; 
}; 
 
exports.sayHello = function() { 
  console.log("Hello " + name); 
}; 

// 在同一目錄下創(chuàng)建 getmodule.js,內(nèi)容是: 
//getmodule.js 
 
var myModule = require("./module"); 
myModule.setName("BYVoid"); 
myModule.sayHello(); 
3.4.2單次加載

在同一個(gè)程序中,同一個(gè)模塊只會(huì)被加載一次,node會(huì)通過將模塊的地址進(jìn)行 hash并存起來,所以不會(huì)加載多次.當(dāng)然這樣的話,你在程序中引用兩次同一個(gè)模塊,他們其實(shí)是一個(gè).

3.4.3.覆蓋exports

模塊通過 exports 暴露相關(guān)的方法或者屬性,未通過此方法暴露的方法和屬性是無法被外界訪問到的(和java C++ C# 中的類差不多)
但是,你不能直接通過以下方式來覆蓋export函數(shù),這樣的話不會(huì)有任何效果

export = function(){
    console.log("Hello");
}

當(dāng)我們只需要暴露一個(gè)方法或?qū)傩缘臅r(shí)候,用exports 就略顯復(fù)雜,我么可以通過以下方式將 exports 進(jìn)行覆蓋:

module.exports = function(){
    console.log("Hello");
}
3.5.創(chuàng)建包

每個(gè)包中有很多的模塊,因?yàn)橹拔覀冎?每個(gè)模塊最好是多帶帶存放在一個(gè)js文件中,那包我們就應(yīng)該存放在一個(gè)文件夾中.并且提供一個(gè)外部訪問的接口(通常是一個(gè)模塊),用于整體管理及使用這個(gè)包的所有功能.

Node.js 在調(diào)用某個(gè)包時(shí),會(huì)首先檢查包中 package.json 文件的 main 字段,將其作為包的接口模塊,如果 package.json 或 main 字段不存在,會(huì)嘗試尋找 index.js 或 index.node 作
為包的接口。

3.5.1.package.json文件

package.json 是 CommonJS 規(guī)定的用來描述包的文件,完全符合規(guī)范的package.json 文件應(yīng)該含有以下字段。

name:包的名稱,必須是唯一的,由小寫英文字母、數(shù)字和下劃線組成,不能包含

空格。

description:包的簡(jiǎn)要說明。

version:符合語義化版本識(shí)別①規(guī)范的版本字符串。

keywords:關(guān)鍵字?jǐn)?shù)組,通常用于搜索。

maintainers:維護(hù)者數(shù)組,每個(gè)元素要包含 name、email (可選)、web (可選)

字段。

contributors:貢獻(xiàn)者數(shù)組,格式與maintainers相同。包的作者應(yīng)該是貢獻(xiàn)者

數(shù)組的第一個(gè)元素。

bugs:提交bug的地址,可以是網(wǎng)址或者電子郵件地址。

licenses:許可證數(shù)組,每個(gè)元素要包含 type (許可證的名稱)和 url (鏈接到

許可證文本的地址)字段。

repositories:倉庫托管地址數(shù)組,每個(gè)元素要包含 type (倉庫的類型,如 git )、

url (倉庫的地址)和 path (相對(duì)于倉庫的路徑,可選)字段。

dependencies:包的依賴,一個(gè)關(guān)聯(lián)數(shù)組,由包名稱和版本號(hào)組成。

下面是一個(gè)完全符合 CommonJS 規(guī)范的 package.json 示例:

{ 
  "name": "mypackage", 
  "description": "Sample package for CommonJS. This package demonstrates the required 
elements of a CommonJS package.", 
  "version": "0.7.0", 
  "keywords": [ 
     "package", 
     "example"  
  ], 
  "maintainers": [ 
     { 
        "name": "Bill Smith", 
        "email": "[email protected]", 
     }  
  ], 
  "contributors": [ 
     { 
        "name": "BYVoid", 
        "web": "http://www.byvoid.com/"  
     }  
  ], 
  "bugs": { 
     "mail": "[email protected]", 
     "web": "http://www.example.com/bugs"  
  }, 
  "licenses": [ 
     { 
        "type": "GPLv2", 
        "url": "http://www.example.org/licenses/gpl.html"  
     }  
  ], 
  "repositories": [ 
     { 
        "type": "git", 
        "url": "http://github.com/BYVoid/mypackage.git"  
     }  
  ], 
  "dependencies": { 
     "webkit": "1.2", 
     "ssl": { 
        "gnutls": ["1.0", "2.0"], 
        "openssl": "0.9.8"  
     }  
  } 
} 
3.6 Node.js包管理器

通過使用Node.js的包管理器,你可以下載到幾乎所有的js包.
獲取一個(gè)包如下

npm install express

以上代碼將會(huì)將express安裝到當(dāng)前項(xiàng)目的文件中
如果要將其安裝在全局(當(dāng)前電腦一次安裝,所有地方都可以使用),可以在參數(shù)中加入 -g,如果是要將其加入項(xiàng)目依賴,可以加入以下參數(shù) --save-dev,這樣node會(huì)自動(dòng)將當(dāng)前包的信息寫入到項(xiàng)目的 package.json 中.

3.7.包的發(fā)布

這個(gè)略過,并不打算發(fā)布,等需要時(shí)看也不遲

3.8.調(diào)試 3.8.1.命令行調(diào)試

調(diào)試其實(shí)方法很多,可以直接在命令行中進(jìn)行單步調(diào)試,以下是nodejs支持的調(diào)試命令:

命令 功能
run 執(zhí)行腳本,在第一行暫停
restart 重新執(zhí)行腳本
cont, c 繼續(xù)執(zhí)行,直到遇到下一個(gè)斷點(diǎn)
next, n 單步執(zhí)行
step, s 單步執(zhí)行并進(jìn)入函數(shù)
out, o 從函數(shù)中步出
setBreakpoint(), sb() 在當(dāng)前行設(shè)置斷點(diǎn)
setBreakpoint(‘f()’), sb(...) 在函數(shù)f的第一行設(shè)置斷點(diǎn)
setBreakpoint(‘script.js’, 20), sb(...) 在 script.js 的第20行設(shè)置斷點(diǎn)
clearBreakpoint, cb(...) 清除所有斷點(diǎn)
backtrace, bt 顯示當(dāng)前的調(diào)用棧
list(5) 顯示當(dāng)前執(zhí)行到的前后5行代碼
watch(expr) 把表達(dá)式 expr 加入監(jiān)視列表
unwatch(expr) 把表達(dá)式 expr 從監(jiān)視列表移除
watchers 顯示監(jiān)視列表中所有的表達(dá)式和值
repl 在當(dāng)前上下文打開即時(shí)求值環(huán)境
kill 終止當(dāng)前執(zhí)行的腳本
scripts 顯示當(dāng)前已加載的所有腳本
version 顯示 V8 的版本
3.8.2.使用 node-inspector 調(diào)試 node.js程序

這個(gè)程序非常好用,雖然我沒有用過,但是看上去很像谷歌瀏覽器的調(diào)試,以后需要時(shí)可以試試看.

4.Node.js核心模塊 4.1.全局對(duì)象

在Node中,有一個(gè)類似在瀏覽器中的window一樣的全局對(duì)象,叫做 global. console,process等都是其子.

如何定義全局對(duì)象就很簡(jiǎn)單了:直接綁定在global上的,定義在最外層的,還有沒有使用var聲明的都是全局對(duì)象.

4.1.1.process對(duì)象

這個(gè)對(duì)象存儲(chǔ)了與當(dāng)前運(yùn)行環(huán)境相關(guān)的很多信息,并且也是標(biāo)準(zhǔn)輸入輸出的最底層接口,我們?cè)谡{(diào)用console.log()時(shí),其背后也是通過process來實(shí)現(xiàn)的.

其含有以下幾個(gè)對(duì)象

process.argv 包含當(dāng)前環(huán)境數(shù)據(jù)

process.stdout 標(biāo)準(zhǔn)輸出接口

process.stdin 標(biāo)準(zhǔn)輸入接口

process.nextTick(callback)的功能是為事件循環(huán)設(shè)置一項(xiàng)任務(wù),Node.js 會(huì)在

下次事件循環(huán)調(diào)響應(yīng)時(shí)調(diào)用 callback。這個(gè)可以用在將兩個(gè)大型的耗時(shí)操作進(jìn)行拆散.

4.1.2.console對(duì)象

這個(gè)對(duì)象是和我們打交道最多的對(duì)象,其含有以下方法:

console.log() 向標(biāo)準(zhǔn)輸出接口打印字符,其有多個(gè)參數(shù),當(dāng)只有一個(gè)參數(shù)時(shí),會(huì)將當(dāng)前參數(shù)轉(zhuǎn)換為字符串并打印出來.

console.error()這個(gè)和剛才的log很相似,只不過這個(gè)是標(biāo)準(zhǔn)錯(cuò)誤輸出,也是就是制造一個(gè)bug!!!!

console.trace() 向標(biāo)準(zhǔn)錯(cuò)誤輸出流輸出當(dāng)前調(diào)用棧

4.2 常用工具util 4.2.1 util.inherits

這個(gè)方法提供了一個(gè)方便的途徑讓我們進(jìn)行繼承操作,用法如下

util.inherits(constructor, superConstructor)

將兩個(gè)對(duì)象進(jìn)行繼承操作

注意,此處繼承只會(huì)繼承原型中定義的屬性和方法!!并且 console.log() 并不會(huì)打印出原型中的屬性或者方法.

4.2.2.util.inspect

util.inspect(object,[showHidden],[depth],[colors]) 是一個(gè)將任一對(duì)象轉(zhuǎn)換為字符串的方法.它不會(huì)調(diào)用對(duì)象的 toString 方法.
除了以上我們介紹的幾個(gè)函數(shù)之外, util還提供了util.isArray()、 util.isRegExp()、
util.isDate()、util.isError() 四個(gè)類型測(cè)試工具,以及 util.format()、util.debug() 等工具。

4.3.事件驅(qū)動(dòng) events

events 是 node最重要的模塊.因?yàn)閚ode整個(gè)運(yùn)行就是基于事件輪詢的.

4.3.1.事件發(fā)生器

events只提供了一個(gè)對(duì)象: events.EventEmitter.這個(gè)對(duì)象的核心就是封裝事件功能.下面的代碼向我們演示了這個(gè)過程:

var events = require("events"); 
 
var emitter = new events.EventEmitter(); 
 
emitter.on("someEvent", function(arg1, arg2) { 
  console.log("listener1", arg1, arg2); 
}); 
 
emitter.on("someEvent", function(arg1, arg2) { 
  console.log("listener2", arg1, arg2); 
}); 
 
emitter.emit("someEvent", "byvoid", 1991); 

這就是EventEmitter最簡(jiǎn)單的用法。接下來我們介紹一下EventEmitter常用的API。

EventEmitter.on(event, listener) 為指定事件注冊(cè)一個(gè)監(jiān)聽器,接受一個(gè)字

符串 event 和一個(gè)回調(diào)函數(shù) listener。

EventEmitter.emit(event, [arg1], [arg2], [...]) 發(fā)射 event 事件,傳

遞若干可選參數(shù)到事件監(jiān)聽器的參數(shù)表。

EventEmitter.once(event, listener) 為指定事件注冊(cè)一個(gè)單次監(jiān)聽器,即

監(jiān)聽器最多只會(huì)觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽器。

EventEmitter.removeListener(event, listener) 移除指定事件的某個(gè)監(jiān)聽

器,listener 必須是該事件已經(jīng)注冊(cè)過的監(jiān)聽器。

EventEmitter.removeAllListeners([event]) 移除所有事件的所有監(jiān)聽器,

如果指定 event,則移除指定事件的所有監(jiān)聽器。

4.3.2. error事件

EventEmitter定義了一個(gè)特殊的叫 error 的事件.當(dāng)error被觸發(fā)時(shí),如果沒有定義的響應(yīng)監(jiān)聽器,則會(huì)退出程序并打印調(diào)用棧.

所以我們要發(fā)射 error 時(shí),必須要為其設(shè)置相應(yīng)的監(jiān)聽器,來捕獲并處理錯(cuò)誤,這樣才不會(huì)導(dǎo)致程序掛掉.

4.3.3.繼承EventEmitter

一般情況下,我們不會(huì)直接用到這個(gè)對(duì)象,而是在繼承中使用它.包括fs,http等都是這樣的操作.

為什么要這樣做呢?原因有兩點(diǎn)。首先,具有某個(gè)實(shí)體功能的對(duì)象實(shí)現(xiàn)事件符合語義,
事件的監(jiān)聽和發(fā)射應(yīng)該是一個(gè)對(duì)象的方法。其次 JavaScript 的對(duì)象機(jī)制是基于原型的,支持部分多重繼承,繼承 EventEmitter 不會(huì)打亂對(duì)象原有的繼承關(guān)系。

4.4.文件系統(tǒng)fs

fs 模塊是文件操作的封裝,它提供了文件的讀取、寫入、更名、刪除、遍歷目錄、鏈接等 POSIX 文件系統(tǒng)操作。與其他模塊不同的是,fs 模塊中所有的操作都提供了異步的和同步的兩個(gè)版本,例如讀取文件內(nèi)容的函數(shù)有異步的 fs.readFile() 和同步的 fs.readFileSync()。我們以幾個(gè)函數(shù)為代表,介紹 fs 常用的功能,并列出 fs 所有函數(shù)的定義和功能。

4.4.1fs.readFile

這個(gè)函數(shù)能夠讀取文件中的內(nèi)容,其用法為:
fs.readFile(filename,[encoding],[callback(err,data)])
以下是調(diào)用示例:

var fs = require("fs"); 
 
fs.readFile("content.txt", "utf-8", function(err, data) { 
  if (err) { 
    console.error(err); 
  } else { 
    console.log(data); 
  } 
}); 
4.4.2.fs.readFileSync

fs.readFileSync(filename, [encoding])是 fs.readFile 同步的版本。它接受的參數(shù)和 fs.readFile 相同,而讀取到的文件內(nèi)容會(huì)以函數(shù)返回值的形式返回。如果有錯(cuò)誤發(fā)生,fs 將會(huì)拋出異常,你需要使用 try 和 catch 捕捉并處理異常。

4.4.3.fs.open

fs.open(path, flags, [mode], [callback(err, fd)])是 POSIX open 函數(shù)的封裝,與 C 語言標(biāo)準(zhǔn)庫中的 fopen 函數(shù)類似。它接受兩個(gè)必選參數(shù),path 為文件的路徑,flags 可以是以下值:

r :以讀取模式打開文件。

r+ :以讀寫模式打開文件。

w :以寫入模式打開文件,如果文件不存在則創(chuàng)建。

w+ :以讀寫模式打開文件,如果文件不存在則創(chuàng)建。

a :以追加模式打開文件,如果文件不存在則創(chuàng)建。

a+ :以讀取追加模式打開文件,如果文件不存在則創(chuàng)建。

mode 參數(shù)用于創(chuàng)建文件時(shí)給文件指定權(quán)限,默認(rèn)是 0666?;卣{(diào)函數(shù)將會(huì)傳遞一個(gè)文
件描述符 fd。

4.4.4.fs.read

fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead, buffer)])是 POSIX read 函數(shù)的封裝,相比 fs.readFile 提供了更底層的接口。

以下是其示例:

var fs = require("fs"); 
 
fs.open("content.txt", "r", function(err, fd) { 
  if (err) { 
    console.error(err); 
    return; 
  } 
   
  var buf = new Buffer(8); 
  fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) { 
    if (err) { 
      console.error(err); 
      return; 
    } 
     
    console.log("bytesRead: " + bytesRead); 
    console.log(buffer); 
  }) 
}); 

當(dāng)然,fs中的函數(shù)是很多的,如果需要,可以去網(wǎng)上進(jìn)行更詳細(xì)的查閱.

4.5 HTTP 服務(wù)器與客戶端

其實(shí)在node中就已經(jīng)封裝了一個(gè)很底層的http模塊,http.Server,幾乎所有的網(wǎng)絡(luò)工作都能通過它來完成.

4.5.1 HTTP服務(wù)器

以下代碼

//app.js 
 
var http = require("http"); 
 
http.createServer(function(req, res) { 
  res.writeHead(200, {"Content-Type": "text/html"}); 
  res.write("

Node.js

"); res.end("

Hello World

"); }).listen(3000); console.log("HTTP server is listening at port 3000.");

會(huì)建立一個(gè)在3000端口監(jiān)聽的程序

4.5.2 GET 請(qǐng)求
//httpserverrequestget.js 
 
var http = require("http"); 
var url = require("url"); 
var util = require("util"); 
 
http.createServer(function(req, res) { 
  res.writeHead(200, {"Content-Type": "text/plain"}); 
  res.end(util.inspect(url.parse(req.url, true))); 
}).listen(3000); 
4.5.3 POST 請(qǐng)求
//httpserverrequestpost.js 
 
var http = require("http"); 
var querystring = require("querystring"); 
var util = require("util"); 
 
http.createServer(function(req, res) { 
  var post = ""; 
 
  req.on("data", function(chunk) { 
    post += chunk; 
  }); 
 
  req.on("end", function() { 
    post = querystring.parse(post); 
    res.end(util.inspect(post)); 
  }); 
 
}).listen(3000); 
4.5.4 http.serverResponse

服務(wù)器不僅要接收數(shù)據(jù),也要返回相應(yīng)的數(shù)據(jù)給客戶端:

http.ServerResponse 是返回給客戶端的信息,決定了用戶最終能看到的結(jié)果。它
也是由 http.Server 的 request 事件發(fā)送的,作為第二個(gè)參數(shù)傳遞,一般簡(jiǎn)稱為
response 或 res。

http.ServerResponse 有三個(gè)重要的成員函數(shù),用于返回響應(yīng)頭、響應(yīng)內(nèi)容以及結(jié)束
請(qǐng)求。

response.writeHead(statusCode, [headers]):向請(qǐng)求的客戶端發(fā)送響應(yīng)頭。statusCode 是 HTTP 狀態(tài)碼,如 200 (請(qǐng)求成功)、404 (未找到)等。headers 是一個(gè)類似關(guān)聯(lián)數(shù)組的對(duì)象,表示響應(yīng)頭的每個(gè)屬性。該函數(shù)在一個(gè)請(qǐng)求內(nèi)最多只能調(diào)用一次,如果不調(diào)用,則會(huì)自動(dòng)生成一個(gè)響應(yīng)頭。

response.write(data, [encoding]):向請(qǐng)求的客戶端發(fā)送響應(yīng)內(nèi)容。data 是一個(gè) Buffer 或字符串,表示要發(fā)送的內(nèi)容。如果 data 是字符串,那么需要指定

encoding 來說明它的編碼方式,默認(rèn)是 utf-8。在 response.end 調(diào)用之前,
response.write 可以被多次調(diào)用。

response.end([data], [encoding]):結(jié)束響應(yīng),告知客戶端所有發(fā)送已經(jīng)完

成。當(dāng)所有要返回的內(nèi)容發(fā)送完畢的時(shí)候,該函數(shù) 必須 被調(diào)用一次。它接受兩個(gè)可
選參數(shù),意義和 response.write 相同。如果不調(diào)用該函數(shù),客戶端將永遠(yuǎn)處于等待狀態(tài)。

4.5.5 HTTP 客戶端

當(dāng)然,node還能充當(dāng)一個(gè)http的客戶端程序來使用 http 模塊提供了兩個(gè)函數(shù) http.request 和 http.get,功能是作為客戶端向 HTTP服務(wù)器發(fā)起請(qǐng)求。

4.5.5.1 http.request

http.request(options, callback) 發(fā)起 HTTP 請(qǐng)求。接受兩個(gè)參數(shù), option 是一個(gè)類似關(guān)聯(lián)數(shù)組的對(duì)象,表示請(qǐng)求的參數(shù), callback是請(qǐng)求的回調(diào)函數(shù)。 option常用的參數(shù)如下所示。

host :請(qǐng)求網(wǎng)站的域名或 IP 地址。

port :請(qǐng)求網(wǎng)站的端口,默認(rèn) 80。

method :請(qǐng)求方法,默認(rèn)是 GET。

path :請(qǐng)求的相對(duì)于根的路徑,默認(rèn)是“/”。QueryString 應(yīng)該包含在其中。例如 /search?query=byvoid。

headers :一個(gè)關(guān)聯(lián)數(shù)組對(duì)象,為請(qǐng)求頭的內(nèi)容。

callback 傳遞一個(gè)參數(shù),為 http.ClientResponse 的實(shí)例。
http.request 返回一個(gè) http.ClientRequest 的實(shí)例。

下面是一個(gè)通過 http.request 發(fā)送 POST 請(qǐng)求的代碼:

//httprequest.js 
 
var http = require("http"); 
var querystring = require("querystring"); 
 
var contents = querystring.stringify({ 
  name: "byvoid", 
  email: "[email protected]", 
  address: "Zijing 2#, Tsinghua University", 
}); 
 
var options = { 
  host: "www.byvoid.com", 
  path: "/application/node/post.php", 
  method: "POST", 
  headers: { 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Content-Length" : contents.length 
  } 
}; 
 
var req = http.request(options, function(res) { 
  res.setEncoding("utf8"); 
  res.on("data", function (data) { 
    console.log(data); 
  }); 
}); 
 
req.write(contents); 
req.end(); 
4.5.5.2 http.get

http.get(options, callback) http 模塊還提供了一個(gè)更加簡(jiǎn)便的方法用于處
理GET請(qǐng)求: http.get。它是 http.request 的簡(jiǎn)化版,唯一的區(qū)別在于http.get
自動(dòng)將請(qǐng)求方法設(shè)為了 GET 請(qǐng)求,同時(shí)不需要手動(dòng)調(diào)用 req.end()。

//httpget.js 
 
var http = require("http"); 
 
http.get({host: "www.byvoid.com"}, function(res) { 
  res.setEncoding("utf8"); 
  res.on("data", function (data) { 
    console.log(data); 
  }); 
}); 

post 和 get 返回的數(shù)據(jù)皆為 http.ClientRequest 對(duì)象.其也提供了write和end函數(shù),使用如下:

//httpresponse.js 
 
var http = require("http"); 
 
var req = http.get({host: "www.byvoid.com"}); 
 
req.on("response", function(res) { 
  res.setEncoding("utf8"); 
  res.on("data", function (data) { 
    console.log(data); 
  }); 
}); 

其還提供了以下函數(shù):

request.abort():終止正在發(fā)送的請(qǐng)求。

request.setTimeout(timeout, [callback]):設(shè)置請(qǐng)求超時(shí)時(shí)間,timeout 為毫秒數(shù)。當(dāng)請(qǐng)求超時(shí)以后,callback 將會(huì)被調(diào)用。

此外還有 request.setNoDelay([noDelay])、request.setSocketKeepAlive
([enable], [initialDelay]) 等函數(shù)。
同時(shí)也有 http.ClientResponse,其與 http:ServerResponse相似,提供... data,end和close,分別在數(shù)據(jù)到達(dá),傳輸結(jié)束和鏈接結(jié)束時(shí)觸發(fā),其中 data 事件傳遞一個(gè)參數(shù) chunk,表示接收到的數(shù)據(jù).

http.ClientResponse 還提供了以下幾個(gè)特殊的函數(shù)。

response.setEncoding([encoding]):設(shè)置默認(rèn)的編碼,當(dāng) data 事件被觸發(fā)

時(shí),數(shù)據(jù)將會(huì)以 encoding 編碼。默認(rèn)值是 null,即不編碼,以 Buffer 的形式存
儲(chǔ)。常用編碼為 utf8。

response.pause():暫停接收數(shù)據(jù)和發(fā)送事件,方便實(shí)現(xiàn)下載功能。

response.resume():從暫停的狀態(tài)中恢復(fù)。

5. 使用Node.js進(jìn)行Web開發(fā) 5.1 使用Express 框架進(jìn)行開發(fā)

安裝npm install -g express

5.2 建立工程
express -t ejs XXXX

接下來的 Nodejs 博客搭建暫未記錄,因?yàn)樯婕暗降闹R(shí)點(diǎn)較多,需要的話最好還是重新讀一次.

6. Node.js 進(jìn)階 6.1 模塊加載機(jī)制

在node中,共有兩種類型的模塊:核心模塊,文件模塊.核心模塊是由node自帶的一些基礎(chǔ)模塊,具有最高的加載優(yōu)先級(jí),文件模塊則是我們自己創(chuàng)建的或者引用的三方模塊.

6.1.1 按路徑查找

如果指定了加載路徑,則有以下兩種查找情況

當(dāng)未指定模塊名稱,而只是制定了文件夾時(shí),node會(huì)自動(dòng)去制定目錄尋找index文件,而index文件的文件類型,按加載順序則有三種:js,json,node.如果這三種類型的index文件都沒有找到,則報(bào)錯(cuò).

當(dāng)指定了文件名稱,但是未指定文件后綴時(shí),node也是按照以上的順序進(jìn)行查找:js,json,node.

6.1.2 通過查找node_modules

當(dāng)我們沒有指定路徑時(shí),node會(huì)在node_moudule目錄中去查找,有趣的是,在這里有一個(gè)很大的性能問題:

比如你在/home/aiello/develop/foot.js中使用require("bar.js"),node會(huì)在當(dāng)前目錄的node_modules文件夾中尋找該模塊,如果未找到,則會(huì)重新往上一級(jí)查找,于是node到/home/aiello/develop這級(jí)目錄進(jìn)行查找,如果還沒有它會(huì)繼續(xù)往上進(jìn)行查找,知道找到根目錄,發(fā)現(xiàn)沒有,于是報(bào)錯(cuò).

能明顯看出來,node在模塊的查找中非常的費(fèi)時(shí),所以我們應(yīng)當(dāng)將模塊放到距離當(dāng)前應(yīng)用最近的目錄,并且最好是指定模塊路徑.

6.2 控制流

在循環(huán)中使用異步方法,將會(huì)遇到

//forloop.js 
 
var fs = require("fs"); 
var files = ["a.txt", "b.txt", "c.txt"]; 
 
for (var i = 0; i < files.length; i++) { 
  fs.readFile(files[i], "utf-8", function(err, contents) { 
    console.log(files[i] + ": " + contents); 
  }); 
} 

這是由于回調(diào)函數(shù)太慢了,早都循環(huán)完了,才會(huì)調(diào)用到回調(diào)函數(shù),所以最后回調(diào)函數(shù)中的i都是等于循環(huán)結(jié)束時(shí)的i(不一定),所以會(huì)有相關(guān)問題,以下代碼將其做一個(gè)閉包封裝,以達(dá)到理想效果:

//forloopclosure.js 
 
var fs = require("fs"); 
var files = ["a.txt", "b.txt", "c.txt"]; 
 
for (var i = 0; i < files.length; i++) { 
  (function(i) { 
    fs.readFile(files[i], "utf-8", function(err, contents) { 
      console.log(files[i] + ": " + contents); 
    }); 
  })(i); 
} 
6.3 Node.js 應(yīng)用部署

普通 Node.js 應(yīng)用存在以下問題:

不支持故障恢復(fù)

沒有日志

無法利用多核提高性能

獨(dú)占端口

需要手動(dòng)啟動(dòng)

6.3.1 日志功能

這個(gè)簡(jiǎn)單,不做概述

6.3.2 故障恢復(fù)

使用cluster模塊,可以實(shí)現(xiàn)多進(jìn)程以及主進(jìn)程與工作進(jìn)程的結(jié)構(gòu).

6.3.3 自動(dòng)啟動(dòng)

制作一個(gè)啟動(dòng)腳本即可

6.3.4 共享端口

虛擬主機(jī)即可

6.4 Node 不是銀彈

so,這個(gè)我知道,他不適合做

計(jì)算密集型

單用戶多任務(wù)

邏輯復(fù)雜的事務(wù)

Unicode與國際化

Javascript 高級(jí)特性

起始位置
PDF 154
頁碼 148

Node.js 編程規(guī)范

起始位置:
PDF 173
頁碼 168

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92433.html

相關(guān)文章

  • 前端補(bǔ)集 - 收藏集 - 掘金

    摘要:原文地址一個(gè)非常適合入門學(xué)習(xí)的博客項(xiàng)目前端掘金一個(gè)非常適合入門學(xué)習(xí)的項(xiàng)目,代碼清晰結(jié)構(gòu)合理新聞前端掘金介紹一個(gè)由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應(yīng)聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應(yīng)聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...

    YorkChen 評(píng)論0 收藏0
  • 前端補(bǔ)集 - 收藏集 - 掘金

    摘要:原文地址一個(gè)非常適合入門學(xué)習(xí)的博客項(xiàng)目前端掘金一個(gè)非常適合入門學(xué)習(xí)的項(xiàng)目,代碼清晰結(jié)構(gòu)合理新聞前端掘金介紹一個(gè)由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應(yīng)聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應(yīng)聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...

    AbnerMing 評(píng)論0 收藏0
  • 2017-10-08 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選讀書思考一的計(jì)算屬性使用開發(fā)調(diào)試開發(fā)者控制臺(tái)中,你可能意想不到的功能中字符串轉(zhuǎn)數(shù)字的陷阱和示例中文設(shè)計(jì)模式單例模式個(gè)人文章設(shè)計(jì)模式工廠模式個(gè)人文章讀書思考二掘金網(wǎng)絡(luò)基礎(chǔ)三傳輸層的筆記學(xué)習(xí)筆記中的屬性學(xué)習(xí) 2017-10-08 前端日?qǐng)?bào) 精選 Node.js Design Patterns - Second Edition讀書思考(一)Vue的計(jì)算屬性_Vue使用typesc...

    Cciradih 評(píng)論0 收藏0
  • 《ECMAScript 6 入門》讀書筆記

    摘要:阮一峰老師開源作品。書上的示例代碼可以通過在線網(wǎng)站代碼調(diào)試工具調(diào)試。 阮一峰老師開源作品。 書上的示例代碼可以通過 在線網(wǎng)站代碼調(diào)試工具 JS Bin 調(diào)試。 作用域 作用域鏈 每個(gè)變量或函數(shù)通過執(zhí)行環(huán)境 (execution context) 定義了其有權(quán)訪問的其他數(shù)據(jù),決定了他們各自的行為; 全局執(zhí)行環(huán)境是最頂層的執(zhí)行環(huán)境,根據(jù)宿主環(huán)境的不同,表示全局執(zhí)行環(huán)境的對(duì)象也不同:在瀏覽...

    qieangel2013 評(píng)論0 收藏0
  • underscore.js 源碼學(xué)習(xí) 讀書筆記(一)

    摘要:所以經(jīng)常會(huì)在一個(gè)源碼中看到寫法吧立即執(zhí)行函數(shù)創(chuàng)建變量,保存全局根變量。 // ================立即執(zhí)行函數(shù)================ // 使用(function(){}())立即執(zhí)行函數(shù),減少全局變量 // ----????----函數(shù)聲明 function (){} 與函數(shù)表達(dá)式 var funName = function(){}----????---- /...

    lx1036 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<