欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:Node.js---菜鳥(niǎo)教程

柚子快報(bào)激活碼778899分享:Node.js---菜鳥(niǎo)教程

http://yzkb.51969.com/

文章目錄

創(chuàng)建第一個(gè)應(yīng)用創(chuàng)建 Node.js 應(yīng)用

NPM 使用介紹使用 npm 命令安裝模塊本地安裝使用 package.json模塊的操作

回調(diào)函數(shù)阻塞代碼實(shí)例非阻塞代碼

事件循環(huán)事件驅(qū)動(dòng)程序

EventEmitterEventEmitter 類(lèi)方法實(shí)例error 事件繼承 EventEmitter

Buffer(緩沖區(qū))Buffer 與字符編碼創(chuàng)建 Buffer 類(lèi)寫(xiě)入緩沖區(qū)從緩沖區(qū)讀取數(shù)據(jù)將 Buffer 轉(zhuǎn)換為 JSON 對(duì)象緩沖區(qū)合并緩沖區(qū)比較拷貝緩沖區(qū)緩沖區(qū)裁剪緩沖區(qū)長(zhǎng)度

Stream(流)從流中讀取數(shù)據(jù)寫(xiě)入流管道流鏈?zhǔn)搅?/p>

模塊系統(tǒng)引入模塊

函數(shù)匿名函數(shù)函數(shù)傳遞是如何讓 HTTP 服務(wù)器工作的

路由全局對(duì)象__filename__dirnamesetTimeout(cb, ms)clearTimeout(t)setInterval(cb, ms)consoleprocessProcess 屬性方法參考手冊(cè)

常用工具util.callbackifyutil.inheritsutil.inspectutil.isArrayutil.isRegExp(object)util.isDate(object)

文件系統(tǒng)異步和同步打開(kāi)文件獲取文件信息寫(xiě)入文件讀取文件關(guān)閉文件截取文件刪除文件創(chuàng)建目錄讀取目錄刪除目錄

GET/POST 請(qǐng)求獲取 GET 請(qǐng)求內(nèi)容獲取 POST 請(qǐng)求內(nèi)容

Web 模塊Web 應(yīng)用架構(gòu)使用 Node 創(chuàng)建 Web 服務(wù)器使用 Node 創(chuàng)建 Web 客戶(hù)端

Express 框架安裝第一個(gè) Express 框架實(shí)例請(qǐng)求和響應(yīng)路由靜態(tài)文件GET 方法POST 方法文件上傳Cookie 管理

RESTful API創(chuàng)建 RESTful獲取用戶(hù)列表:添加用戶(hù)顯示用戶(hù)詳情刪除用戶(hù)

多進(jìn)程exec() 方法

創(chuàng)建第一個(gè)應(yīng)用

讓我們先了解下 Node.js 應(yīng)用是由哪幾部分組成的:

require 指令:在 Node.js 中,使用 require 指令來(lái)加載和引入模塊,引入的模塊可以是內(nèi)置模塊,也可以是第三方模塊或自定義模塊。 創(chuàng)建服務(wù)器:服務(wù)器可以監(jiān)聽(tīng)客戶(hù)端的請(qǐng)求,類(lèi)似于 Apache 、Nginx 等 HTTP 服務(wù)器。 接收請(qǐng)求與響應(yīng)請(qǐng)求: 服務(wù)器很容易創(chuàng)建,客戶(hù)端可以使用瀏覽器或終端發(fā)送 HTTP 請(qǐng)求,服務(wù)器接收請(qǐng)求后返回響應(yīng)數(shù)據(jù)。

創(chuàng)建 Node.js 應(yīng)用

步驟一、使用 require 指令來(lái)加載和引入模塊

const module = require('module-name');

其中,module-name 可以是一個(gè)文件路徑(相對(duì)或絕對(duì)路徑),也可以是一個(gè)模塊名稱(chēng),如果是一個(gè)模塊名稱(chēng),Node.js 會(huì)自動(dòng)從 node_modules 目錄中查找該模塊。

我們使用 require 指令來(lái)載入 http 模塊,并將實(shí)例化的 HTTP 賦值給變量 http,實(shí)例如下:

var http = require("http");

步驟二、創(chuàng)建服務(wù)器 接下來(lái)我們使用 http.createServer() 方法創(chuàng)建服務(wù)器,并使用 listen 方法綁定 8888 端口。 函數(shù)通過(guò) request, response 參數(shù)來(lái)接收和響應(yīng)數(shù)據(jù)。

實(shí)例如下,在你項(xiàng)目的根目錄下創(chuàng)建一個(gè)叫 server.js 的文件,并寫(xiě)入以下代碼:

var http = require('http');

http.createServer(function (request, response) {

// 發(fā)送 HTTP 頭部

// HTTP 狀態(tài)值: 200 : OK

// 內(nèi)容類(lèi)型: text/plain

response.writeHead(200, {'Content-Type': 'text/plain'});

// 發(fā)送響應(yīng)數(shù)據(jù) "Hello World"

response.end('Hello World\n');

}).listen(8888);

// 終端打印如下信息

console.log('Server running at http://127.0.0.1:8888/');

以上代碼我們完成了一個(gè)可以工作的 HTTP 服務(wù)器。

使用 node 命令執(zhí)行以上的代碼:

node server.js

接下來(lái),打開(kāi)瀏覽器訪問(wèn) http://127.0.0.1:8888/,你會(huì)看到一個(gè)寫(xiě)著 "Hello World"的網(wǎng)頁(yè)。 分析Node.js 的 HTTP 服務(wù)器:

第一行請(qǐng)求(require)Node.js 自帶的 http 模塊,并且把它賦值給 http 變量。接下來(lái)我們調(diào)用 http 模塊提供的函數(shù): createServer 。這個(gè)函數(shù)會(huì)返回 一個(gè)對(duì)象,這個(gè)對(duì)象有一個(gè)叫做 listen 的方法,這個(gè)方法有一個(gè)數(shù)值參數(shù), 指定這個(gè) HTTP 服務(wù)器監(jiān)聽(tīng)的端口號(hào)。

NPM 使用介紹

NPM是隨同NodeJS一起安裝的包管理工具,能解決NodeJS代碼部署上的很多問(wèn)題。

可以通過(guò)輸入 “npm -v” 來(lái)測(cè)試是否成功安裝。

使用 npm 命令安裝模塊

以下實(shí)例,我們使用 npm 命令安裝常用的 Node.js web框架模塊 express:

npm install express

安裝好之后,express 包就放在了工程目錄下的 node_modules 目錄中,因此在代碼中只需要通過(guò) require(‘express’) 的方式就好,無(wú)需指定第三方包路徑。

var express = require('express');

本地安裝

將安裝包放在 ./node_modules 下(運(yùn)行 npm 命令時(shí)所在的目錄),如果沒(méi)有 node_modules 目錄,會(huì)在當(dāng)前執(zhí)行 npm 命令的目錄下生成 node_modules 目錄??梢酝ㄟ^(guò) require() 來(lái)引入本地安裝的包。

使用 package.json

package.json 位于模塊的目錄下,用于定義包的屬性。

模塊的操作

卸載模塊

npm uninstall express

卸載后,你可以到 /node_modules/ 目錄下查看包是否還存在,或者使用以下命令查看:

npm ls

更新模塊

npm update express

搜索模塊

npm search express

回調(diào)函數(shù)

Node.js 異步編程的直接體現(xiàn)就是回調(diào)。

異步編程依托于回調(diào)來(lái)實(shí)現(xiàn),但不能說(shuō)使用了回調(diào)后程序就異步化了。

回調(diào)函數(shù)在完成任務(wù)后就會(huì)被調(diào)用,Node 使用了大量的回調(diào)函數(shù),Node 所有 API 都支持回調(diào)函數(shù)。

例如,我們可以一邊讀取文件,一邊執(zhí)行其他命令,在文件讀取完成后,我們將文件內(nèi)容作為回調(diào)函數(shù)的參數(shù)返回。這樣在執(zhí)行代碼時(shí)就沒(méi)有阻塞或等待文件 I/O 操作。這就大大提高了 Node.js 的性能,可以處理大量的并發(fā)請(qǐng)求。

回調(diào)函數(shù)一般作為函數(shù)的最后一個(gè)參數(shù)出現(xiàn):

function foo1(name, age, callback) { }

function foo2(value, callback1, callback2) { }

阻塞代碼實(shí)例

創(chuàng)建一個(gè)文件 input.txt ,內(nèi)容如下:

菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com

創(chuàng)建 main.js 文件, 代碼如下:

var fs = require("fs");

var data = fs.readFileSync('input.txt');

console.log(data.toString());

console.log("程序執(zhí)行結(jié)束!");

以上代碼執(zhí)行結(jié)果如下:

非阻塞代碼

創(chuàng)建 main.js 文件, 代碼如下:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {

if (err) return console.error(err);

console.log(data.toString());

});

console.log("程序執(zhí)行結(jié)束!");

以上兩個(gè)實(shí)例我們了解了阻塞與非阻塞調(diào)用的不同。第一個(gè)實(shí)例在文件讀取完后才執(zhí)行程序。 第二個(gè)實(shí)例我們不需要等待文件讀取完,這樣就可以在讀取文件時(shí)同時(shí)執(zhí)行接下來(lái)的代碼,大大提高了程序的性能。

因此,阻塞是按順序執(zhí)行的,而非阻塞是不需要按順序的,所以如果需要處理回調(diào)函數(shù)的參數(shù),我們就需要寫(xiě)在回調(diào)函數(shù)內(nèi)。

事件循環(huán)

事件驅(qū)動(dòng)程序

Node.js 使用事件驅(qū)動(dòng)模型,當(dāng)web server接收到請(qǐng)求,就把它關(guān)閉然后進(jìn)行處理,然后去服務(wù)下一個(gè)web請(qǐng)求。

當(dāng)這個(gè)請(qǐng)求完成,它被放回處理隊(duì)列,當(dāng)?shù)竭_(dá)隊(duì)列開(kāi)頭,這個(gè)結(jié)果被返回給用戶(hù)。

這個(gè)模型非常高效可擴(kuò)展性非常強(qiáng),因?yàn)?webserver 一直接受請(qǐng)求而不等待任何讀寫(xiě)操作。

在事件驅(qū)動(dòng)模型中,會(huì)生成一個(gè)主循環(huán)來(lái)監(jiān)聽(tīng)事件,當(dāng)檢測(cè)到事件時(shí)觸發(fā)回調(diào)函數(shù)。

Node.js 有多個(gè)內(nèi)置的事件,我們可以通過(guò)引入 events 模塊,并通過(guò)實(shí)例化 EventEmitter 類(lèi)來(lái)綁定和監(jiān)聽(tīng)事件,如下實(shí)例:

創(chuàng)建 main.js 文件,代碼如下所示:

// 引入 events 模塊

var events = require('events');

// 創(chuàng)建 eventEmitter 對(duì)象

var eventEmitter = new events.EventEmitter();

// 創(chuàng)建事件處理程序

var connectHandler = function connected() {

console.log('連接成功。');

// 觸發(fā) data_received 事件

eventEmitter.emit('data_received');

}

// 綁定 connection 事件處理程序

eventEmitter.on('connection', connectHandler);

// 使用匿名函數(shù)綁定 data_received 事件

eventEmitter.on('data_received', function(){

console.log('數(shù)據(jù)接收成功。');

});

// 觸發(fā) connection 事件

eventEmitter.emit('connection');

console.log("程序執(zhí)行完畢。");

EventEmitter

Node.js 所有的異步 I/O 操作在完成時(shí)都會(huì)發(fā)送一個(gè)事件到事件隊(duì)列。

EventEmitter 類(lèi)

events 模塊只提供了一個(gè)對(duì)象: events.EventEmitter。EventEmitter 的核心就是事件觸發(fā)與事件監(jiān)聽(tīng)器功能的封裝。

你可以通過(guò)require(“events”);來(lái)訪問(wèn)該模塊。

// 引入 events 模塊

var events = require('events');

// 創(chuàng)建 eventEmitter 對(duì)象

var eventEmitter = new events.EventEmitter();

下面我們用一個(gè)簡(jiǎn)單的例子說(shuō)明 EventEmitter 的用法:

//event.js 文件

var EventEmitter = require('events').EventEmitter;

var event = new EventEmitter();

event.on('some_event', function() {

console.log('some_event 事件觸發(fā)');

});

setTimeout(function() {

event.emit('some_event');

}, 1000);

運(yùn)行這段代碼,1 秒后控制臺(tái)輸出了 ‘some_event 事件觸發(fā)’。

其原理是 event 對(duì)象注冊(cè)了事件 some_event 的一個(gè)監(jiān)聽(tīng)器,然后我們通過(guò) setTimeout 在 1000 毫秒以后向 event 對(duì)象發(fā)送事件 some_event,此時(shí)會(huì)調(diào)用some_event 的監(jiān)聽(tīng)器。

EventEmitter 的每個(gè)事件由一個(gè)事件名和若干個(gè)參數(shù)組成,事件名是一個(gè)字符串,通常表達(dá)一定的語(yǔ)義。對(duì)于每個(gè)事件,EventEmitter 支持 若干個(gè)事件監(jiān)聽(tīng)器。

當(dāng)事件觸發(fā)時(shí),注冊(cè)到這個(gè)事件的事件監(jiān)聽(tīng)器被依次調(diào)用,事件參數(shù)作為回調(diào)函數(shù)參數(shù)傳遞。

讓我們以下面的例子解釋這個(gè)過(guò)程:

//event.js 文件

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', 'arg1 參數(shù)', 'arg2 參數(shù)');

以上例子中,emitter 為事件 someEvent 注冊(cè)了兩個(gè)事件監(jiān)聽(tīng)器,然后觸發(fā)了 someEvent 事件。

運(yùn)行結(jié)果中可以看到兩個(gè)事件監(jiān)聽(tīng)器回調(diào)函數(shù)被先后調(diào)用。 這就是EventEmitter最簡(jiǎn)單的用法。

EventEmitter 提供了多個(gè)屬性,如 on 和 emit。on 函數(shù)用于綁定事件函數(shù),emit 屬性用于觸發(fā)一個(gè)事件。接下來(lái)我們來(lái)具體看下 EventEmitter 的屬性介紹。

方法

addListener(event, listener) 為指定事件添加一個(gè)監(jiān)聽(tīng)器到監(jiān)聽(tīng)器數(shù)組的尾部。on(event, listener) 為指定事件注冊(cè)一個(gè)監(jiān)聽(tīng)器,接受一個(gè)字符串 event 和一個(gè)回調(diào)函數(shù)。

server.on('connection', function (stream) {

console.log('someone connected!');

});

once(event, listener) 為指定事件注冊(cè)一個(gè)單次監(jiān)聽(tīng)器,即 監(jiān)聽(tīng)器最多只會(huì)觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽(tīng)器。

server.once('connection', function (stream) {

console.log('Ah, we have our first user!');

});

removeListener(event, listener) 移除指定事件的某個(gè)監(jiān)聽(tīng)器,監(jiān)聽(tīng)器必須是該事件已經(jīng)注冊(cè)過(guò)的監(jiān)聽(tīng)器。

它接受兩個(gè)參數(shù),第一個(gè)是事件名稱(chēng),第二個(gè)是回調(diào)函數(shù)名稱(chēng)。

var callback = function(stream) {

console.log('someone connected!');

};

server.on('connection', callback);

// ...

server.removeListener('connection', callback);

類(lèi)方法 listenerCount(emitter, event) 返回指定事件的監(jiān)聽(tīng)器數(shù)量。

events.emitter.listenerCount(eventName) //推薦

實(shí)例

以下實(shí)例通過(guò) connection(連接)事件演示了 EventEmitter 類(lèi)的應(yīng)用。

創(chuàng)建 main.js 文件,代碼如下:

var events = require('events');

var eventEmitter = new events.EventEmitter();

// 監(jiān)聽(tīng)器 #1

var listener1 = function listener1() {

console.log('監(jiān)聽(tīng)器 listener1 執(zhí)行。');

}

// 監(jiān)聽(tīng)器 #2

var listener2 = function listener2() {

console.log('監(jiān)聽(tīng)器 listener2 執(zhí)行。');

}

// 綁定 connection 事件,處理函數(shù)為 listener1

eventEmitter.addListener('connection', listener1);

// 綁定 connection 事件,處理函數(shù)為 listener2

eventEmitter.on('connection', listener2);

var eventListeners = eventEmitter.listenerCount('connection');

console.log(eventListeners + " 個(gè)監(jiān)聽(tīng)器監(jiān)聽(tīng)連接事件。");

// 處理 connection 事件

eventEmitter.emit('connection');

// 移除監(jiān)綁定的 listener1 函數(shù)

eventEmitter.removeListener('connection', listener1);

console.log("listener1 不再受監(jiān)聽(tīng)。");

// 觸發(fā)連接事件

eventEmitter.emit('connection');

eventListeners = eventEmitter.listenerCount('connection');

console.log(eventListeners + " 個(gè)監(jiān)聽(tīng)器監(jiān)聽(tīng)連接事件。");

console.log("程序執(zhí)行完畢。");

error 事件

EventEmitter 定義了一個(gè)特殊的事件 error,它包含了錯(cuò)誤的語(yǔ)義,我們?cè)谟龅?異常的時(shí)候通常會(huì)觸發(fā) error 事件。 我們一般要為會(huì)觸發(fā) error 事件的對(duì)象設(shè)置監(jiān)聽(tīng)器,避免遇到錯(cuò)誤后整個(gè)程序崩潰。例如:

var events = require('events');

var emitter = new events.EventEmitter();

emitter.emit('error');

繼承 EventEmitter

大多數(shù)時(shí)候我們不會(huì)直接使用 EventEmitter,而是在對(duì)象中繼承它。包括 fs、net、 http 在內(nèi)的,只要是支持事件響應(yīng)的核心模塊都是 EventEmitter 的子類(lèi)。

Buffer(緩沖區(qū))

在 Node.js 中,Buffer 類(lèi)是隨 Node 內(nèi)核一起發(fā)布的核心庫(kù)。Buffer 庫(kù)為 Node.js 帶來(lái)了一種存儲(chǔ)原始數(shù)據(jù)的方法,可以讓 Node.js 處理二進(jìn)制數(shù)據(jù),每當(dāng)需要在 Node.js 中處理I/O操作中移動(dòng)的數(shù)據(jù)時(shí),就有可能使用 Buffer 庫(kù)。

Buffer 與字符編碼

Buffer 實(shí)例一般用于表示編碼字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六進(jìn)制編碼的數(shù)據(jù)。

const buf = Buffer.from('runoob', 'ascii');

// 輸出 72756e6f6f62

console.log(buf.toString('hex'));

// 輸出 cnVub29i

console.log(buf.toString('base64'));

創(chuàng)建 Buffer 類(lèi)

Buffer 提供了以下 API 來(lái)創(chuàng)建 Buffer 類(lèi):

// 創(chuàng)建一個(gè)長(zhǎng)度為 10、且用 0 填充的 Buffer。

const buf1 = Buffer.alloc(10);

// 創(chuàng)建一個(gè)長(zhǎng)度為 10、且用 0x1 填充的 Buffer。

const buf2 = Buffer.alloc(10, 1);

// 創(chuàng)建一個(gè)長(zhǎng)度為 10、且未初始化的 Buffer。

// 這個(gè)方法比調(diào)用 Buffer.alloc() 更快,

// 但返回的 Buffer 實(shí)例可能包含舊數(shù)據(jù),

// 因此需要使用 fill() 或 write() 重寫(xiě)。

const buf3 = Buffer.allocUnsafe(10);

// 創(chuàng)建一個(gè)包含 [0x1, 0x2, 0x3] 的 Buffer。

const buf4 = Buffer.from([1, 2, 3]);

// 創(chuàng)建一個(gè)包含 UTF-8 字節(jié) [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。

const buf5 = Buffer.from('tést');

// 創(chuàng)建一個(gè)包含 Latin-1 字節(jié) [0x74, 0xe9, 0x73, 0x74] 的 Buffer。

const buf6 = Buffer.from('tést', 'latin1');

寫(xiě)入緩沖區(qū)

語(yǔ)法:

buf.write(string[, offset[, length]][, encoding])

參數(shù):

string - 寫(xiě)入緩沖區(qū)的字符串。 offset - 緩沖區(qū)開(kāi)始寫(xiě)入的索引值,默認(rèn)為 0 。 length - 寫(xiě)入的字節(jié)數(shù),默認(rèn)為 buffer.length encoding - 使用的編碼。默認(rèn)為 ‘utf8’ 。 根據(jù) encoding 的字符編碼寫(xiě)入 string 到 buf 中的 offset 位置。 length 參數(shù)是寫(xiě)入的字節(jié)數(shù)。 返回值 返回實(shí)際寫(xiě)入的大小。 實(shí)例

buf = Buffer.alloc(256);

len = buf.write("www.runoob.com");

console.log("寫(xiě)入字節(jié)數(shù) : "+ len);

從緩沖區(qū)讀取數(shù)據(jù)

語(yǔ)法

buf.toString([encoding[, start[, end]]])

參數(shù)

encoding - 使用的編碼。默認(rèn)為 ‘utf8’ 。 start - 指定開(kāi)始讀取的索引位置,默認(rèn)為 0。 end - 結(jié)束位置,默認(rèn)為緩沖區(qū)的末尾。

返回值 解碼緩沖區(qū)數(shù)據(jù)并使用指定的編碼返回字符串。

實(shí)例

buf = Buffer.alloc(26);

for (var i = 0 ; i < 26 ; i++) {

buf[i] = i + 97;

}

console.log( buf.toString('ascii')); // 輸出: abcdefghijklmnopqrstuvwxyz

console.log( buf.toString('ascii',0,5)); //使用 'ascii' 編碼, 并輸出: abcde

console.log( buf.toString('utf8',0,5)); // 使用 'utf8' 編碼, 并輸出: abcde

console.log( buf.toString(undefined,0,5)); // 使用默認(rèn)的 'utf8' 編碼, 并輸出: abcde

將 Buffer 轉(zhuǎn)換為 JSON 對(duì)象

語(yǔ)法

buf.toJSON()

返回值 返回 JSON 對(duì)象。

實(shí)例

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);

const json = JSON.stringify(buf);

// 輸出: {"type":"Buffer","data":[1,2,3,4,5]}

console.log(json);

const copy = JSON.parse(json, (key, value) => {

return value && value.type === 'Buffer' ?

Buffer.from(value.data) :

value;

});

// 輸出:

console.log(copy);

JSON 通常用于與服務(wù)端交換數(shù)據(jù)。 我們可以使用 JSON.parse() 方法將數(shù)據(jù)轉(zhuǎn)換為 JavaScript 對(duì)象。

緩沖區(qū)合并

語(yǔ)法

Buffer.concat(list[, totalLength])

參數(shù)

list - 用于合并的 Buffer 對(duì)象數(shù)組列表。 totalLength - 指定合并后Buffer對(duì)象的總長(zhǎng)度。

返回值 返回一個(gè)多個(gè)成員合并的新 Buffer 對(duì)象。

實(shí)例

var buffer1 = Buffer.from(('菜鳥(niǎo)教程'));

var buffer2 = Buffer.from(('www.runoob.com'));

var buffer3 = Buffer.concat([buffer1,buffer2]);

console.log("buffer3 內(nèi)容: " + buffer3.toString());

緩沖區(qū)比較

語(yǔ)法

buf.compare(otherBuffer);

參數(shù)

otherBuffer - 與 buf 對(duì)象比較的另外一個(gè) Buffer 對(duì)象。

返回值 返回一個(gè)數(shù)字,表示 buf 在 otherBuffer 之前,之后或相同。

實(shí)例

var buffer1 = Buffer.from('ABC');

var buffer2 = Buffer.from('ABCD');

var result = buffer1.compare(buffer2);

if(result < 0) {

console.log(buffer1 + " 在 " + buffer2 + "之前");

}else if(result == 0){

console.log(buffer1 + " 與 " + buffer2 + "相同");

}else {

console.log(buffer1 + " 在 " + buffer2 + "之后");

}

拷貝緩沖區(qū)

語(yǔ)法

buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])

參數(shù)

targetBuffer - 要拷貝的 Buffer 對(duì)象。 targetStart - 數(shù)字, 可選, 默認(rèn): 0 sourceStart - 數(shù)字, 可選, 默認(rèn): 0 sourceEnd - 數(shù)字, 可選, 默認(rèn): buffer.length

實(shí)例

var buf1 = Buffer.from('abcdefghijkl');

var buf2 = Buffer.from('RUNOOB');

//將 buf2 插入到 buf1 指定位置上

buf2.copy(buf1, 2);

console.log(buf1.toString());

緩沖區(qū)裁剪

語(yǔ)法

buf.slice([start[, end]])

參數(shù)

start - 數(shù)字, 可選, 默認(rèn): 0 end - 數(shù)字, 可選, 默認(rèn): buffer.length

返回值 返回一個(gè)新的緩沖區(qū),它和舊緩沖區(qū)指向同一塊內(nèi)存,但是從索引 start 到 end 的位置剪切。

實(shí)例

var buffer1 = Buffer.from('runoob');

// 剪切緩沖區(qū)

var buffer2 = buffer1.slice(0,2);

console.log("buffer2 content: " + buffer2.toString());

緩沖區(qū)長(zhǎng)度

語(yǔ)法

buf.length;

返回值 返回 Buffer 對(duì)象所占據(jù)的內(nèi)存長(zhǎng)度。

實(shí)例

var buffer = Buffer.from('www.runoob.com');

// 緩沖區(qū)長(zhǎng)度

console.log("buffer length: " + buffer.length);

Stream(流)

Stream 是一個(gè)抽象接口,Node 中有很多對(duì)象實(shí)現(xiàn)了這個(gè)接口。

所有的 Stream 對(duì)象都是 EventEmitter 的實(shí)例。常用的事件有:

data - 當(dāng)有數(shù)據(jù)可讀時(shí)觸發(fā)。 end - 沒(méi)有更多的數(shù)據(jù)可讀時(shí)觸發(fā)。 error - 在接收和寫(xiě)入過(guò)程中發(fā)生錯(cuò)誤時(shí)觸發(fā)。 finish - 所有數(shù)據(jù)已被寫(xiě)入到底層系統(tǒng)時(shí)觸發(fā)。

從流中讀取數(shù)據(jù)

創(chuàng)建 input.txt 文件,內(nèi)容如下:

菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com

創(chuàng)建 main.js 文件, 代碼如下:

var fs = require("fs");

var data = '';

// 創(chuàng)建可讀流

var readerStream = fs.createReadStream('input.txt');

// 設(shè)置編碼為 utf8。

readerStream.setEncoding('UTF8');

// 處理流事件 --> data, end, and error

readerStream.on('data', function(chunk) {

data += chunk;

});

readerStream.on('end',function(){

console.log(data);

});

readerStream.on('error', function(err){

console.log(err.stack);

});

console.log("程序執(zhí)行完畢");

寫(xiě)入流

var fs = require("fs");

var data = '菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com';

// 創(chuàng)建一個(gè)可以寫(xiě)入的流,寫(xiě)入到文件 output.txt 中

var writerStream = fs.createWriteStream('output.txt');

// 使用 utf8 編碼寫(xiě)入數(shù)據(jù)

writerStream.write(data,'UTF8');

// 標(biāo)記文件末尾

writerStream.end();

// 處理流事件 --> finish、error

writerStream.on('finish', function() {

console.log("寫(xiě)入完成。");

});

writerStream.on('error', function(err){

console.log(err.stack);

});

console.log("程序執(zhí)行完畢");

管道流

管道提供了一個(gè)輸出流到輸入流的機(jī)制。通常我們用于從一個(gè)流中獲取數(shù)據(jù)并將數(shù)據(jù)傳遞到另外一個(gè)流中。

以下實(shí)例我們通過(guò)讀取一個(gè)文件內(nèi)容并將內(nèi)容寫(xiě)入到另外一個(gè)文件中。

設(shè)置 input.txt 文件內(nèi)容如下:

菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com

管道流操作實(shí)例

創(chuàng)建 main.js 文件, 代碼如下:

var fs = require("fs");

// 創(chuàng)建一個(gè)可讀流

var readerStream = fs.createReadStream('input.txt');

// 創(chuàng)建一個(gè)可寫(xiě)流

var writerStream = fs.createWriteStream('output.txt');

// 管道讀寫(xiě)操作

// 讀取 input.txt 文件內(nèi)容,并將內(nèi)容寫(xiě)入到 output.txt 文件中

readerStream.pipe(writerStream);

console.log("程序執(zhí)行完畢");

鏈?zhǔn)搅?/p>

鏈?zhǔn)绞峭ㄟ^(guò)連接輸出流到另外一個(gè)流并創(chuàng)建多個(gè)流操作鏈的機(jī)制。鏈?zhǔn)搅饕话阌糜诠艿啦僮鳌?/p>

接下來(lái)我們就是用管道和鏈?zhǔn)絹?lái)壓縮和解壓文件。

創(chuàng)建 compress.js 文件, 代碼如下:

var fs = require("fs");

var zlib = require('zlib');

// 壓縮 input.txt 文件為 input.txt.gz

fs.createReadStream('input.txt')

.pipe(zlib.createGzip())

.pipe(fs.createWriteStream('input.txt.gz'));

console.log("文件壓縮完成。");

執(zhí)行完以上操作后,我們可以看到當(dāng)前目錄下生成了 input.txt 的壓縮文件 input.txt.gz。

接下來(lái),讓我們來(lái)解壓該文件,創(chuàng)建 decompress.js 文件,代碼如下:

var fs = require("fs");

var zlib = require('zlib');

// 解壓 input.txt.gz 文件為 input.txt

fs.createReadStream('input.txt.gz')

.pipe(zlib.createGunzip())

.pipe(fs.createWriteStream('input.txt'));

console.log("文件解壓完成。");

模塊系統(tǒng)

一個(gè) Node.js 文件就是一個(gè)模塊,這個(gè)文件可能是JavaScript 代碼、JSON 或者編譯過(guò)的C/C++ 擴(kuò)展。

引入模塊

我們創(chuàng)建一個(gè) main.js 文件并引入 hello 模塊,代碼如下:

var hello = require('./hello');

hello.world();

以上實(shí)例中,代碼 require(‘./hello’) 引入了當(dāng)前目錄下的 hello.js 文件(./ 為當(dāng)前目錄,node.js 默認(rèn)后綴為 js)。

接下來(lái)我們就來(lái)創(chuàng)建 hello.js 文件,代碼如下:

exports.world = function() {

console.log('Hello World');

}

有時(shí)候我們只是想把一個(gè)對(duì)象封裝到模塊中,格式如下:

//hello.js

function Hello() {

var name;

this.setName = function(thyName) {

name = thyName;

};

this.sayHello = function() {

console.log('Hello ' + name);

};

};

module.exports = Hello;

這樣就可以直接獲得這個(gè)對(duì)象了:

//main.js

var Hello = require('./hello');

hello = new Hello();

hello.setName('BYVoid');

hello.sayHello();

函數(shù)

在 JavaScript中,一個(gè)函數(shù)可以作為另一個(gè)函數(shù)的參數(shù)。我們可以先定義一個(gè)函數(shù),然后傳遞,也可以在傳遞參數(shù)的地方直接定義函數(shù)。

function say(word) {

console.log(word);

}

function execute(someFunction, value) {

someFunction(value);

}

execute(say, "Hello");

以上代碼中,我們把 say 函數(shù)作為 execute 函數(shù)的第一個(gè)變量進(jìn)行了傳遞。這里傳遞的不是 say 的返回值,而是 say 本身!

這樣一來(lái), say 就變成了execute 中的本地變量 someFunction ,execute 可以通過(guò)調(diào)用 someFunction() (帶括號(hào)的形式)來(lái)使用 say 函數(shù)。

當(dāng)然,因?yàn)?say 有一個(gè)變量, execute 在調(diào)用 someFunction 時(shí)可以傳遞這樣一個(gè)變量。

匿名函數(shù)

我們可以把一個(gè)函數(shù)作為變量傳遞。但是我們不一定要"先定義,再傳遞"。

我們可以直接在另一個(gè)函數(shù)的括號(hào)中定義和傳遞這個(gè)函數(shù):

function execute(someFunction, value) {

someFunction(value);

}

execute(function(word){ console.log(word) }, "Hello");

我們?cè)?execute 接受第一個(gè)參數(shù)的地方直接定義了我們準(zhǔn)備傳遞給 execute 的函數(shù)。

用這種方式,我們甚至不用給這個(gè)函數(shù)起名字,這也是為什么它被叫做匿名函數(shù) 。

函數(shù)傳遞是如何讓 HTTP 服務(wù)器工作的

var http = require("http");

http.createServer(function(request, response) {

response.writeHead(200, {"Content-Type": "text/plain"});

response.write("Hello World");

response.end();

}).listen(8888);

現(xiàn)在它看上去應(yīng)該清晰了很多:我們向 createServer 函數(shù)傳遞了一個(gè)匿名函數(shù)。

路由

我們需要的所有數(shù)據(jù)都會(huì)包含在 request 對(duì)象中,該對(duì)象作為 onRequest() 回調(diào)函數(shù)的第一個(gè)參數(shù)傳遞。

但是為了解析這些數(shù)據(jù),我們需要額外的 Node.JS 模塊,它們分別是 url 和 querystring 模塊。

url.parse(string).query

|

url.parse(string).pathname |

| |

| |

------|-------------------

http://localhost:8888/start?foo=bar&hello=world

--- -----

| |

| |

querystring.parse(queryString)["foo"] |

|

querystring.parse(queryString)["hello"]

現(xiàn)在我們來(lái)給 onRequest() 函數(shù)加上一些邏輯,用來(lái)找出瀏覽器請(qǐng)求的 URL 路徑:

var http = require("http");

var url = require("url");

function start() {

function onRequest(request, response) {

var pathname = url.parse(request.url).pathname;

console.log("Request for " + pathname + " received.");

response.writeHead(200, {"Content-Type": "text/plain"});

response.write("Hello World");

response.end();

}

http.createServer(onRequest).listen(8888);

console.log("Server has started.");

}

exports.start = start;

現(xiàn)在我們可以來(lái)編寫(xiě)路由了,建立一個(gè)名為 router.js 的文件,添加以下內(nèi)容:

function route(pathname) {

console.log("About to route a request for " + pathname);

}

exports.route = route;

如你所見(jiàn),這段代碼什么也沒(méi)干,不過(guò)對(duì)于現(xiàn)在來(lái)說(shuō)這是應(yīng)該的。在添加更多的邏輯以前,我們先來(lái)看看如何把路由和服務(wù)器整合起來(lái)。

首先,我們來(lái)擴(kuò)展一下服務(wù)器的 start() 函數(shù),以便將路由函數(shù)作為參數(shù)傳遞過(guò)去,server.js 文件代碼如下

var http = require("http");

var url = require("url");

function start(route) {

function onRequest(request, response) {

var pathname = url.parse(request.url).pathname;

console.log("Request for " + pathname + " received.");

route(pathname);

response.writeHead(200, {"Content-Type": "text/plain"});

response.write("Hello World");

response.end();

}

http.createServer(onRequest).listen(8888);

console.log("Server has started.");

}

exports.start = start;

同時(shí),我們會(huì)相應(yīng)擴(kuò)展 index.js,使得路由函數(shù)可以被注入到服務(wù)器中:

var server = require("./server");

var router = require("./router");

server.start(router.route);

如果現(xiàn)在啟動(dòng)應(yīng)用(node index.js,始終記得這個(gè)命令行),隨后請(qǐng)求一個(gè)URL,你將會(huì)看到應(yīng)用輸出相應(yīng)的信息,這表明我們的HTTP服務(wù)器已經(jīng)在使用路由模塊了,并會(huì)將請(qǐng)求的路徑傳遞給路由:

瀏覽器訪問(wèn) http://127.0.0.1:8888/,輸出結(jié)果如下:

全局對(duì)象

全局對(duì)象(Global Object),它及其所有屬性都可以在程序的任何地方訪問(wèn)。

Node.js 中的全局對(duì)象是 global,所有全局變量都是 global 對(duì)象的屬性。

在 Node.js 我們可以直接訪問(wèn)到 global 的屬性,而不需要在應(yīng)用中包含它。

__filename

__filename 表示當(dāng)前正在執(zhí)行的腳本的文件名。它將輸出文件所在位置的絕對(duì)路徑。

實(shí)例 創(chuàng)建文件 main.js ,代碼如下所示:

// 輸出全局變量 __filename 的值

console.log( __filename );

__dirname

__dirname 表示當(dāng)前執(zhí)行腳本所在的目錄。

實(shí)例 創(chuàng)建文件 main.js ,代碼如下所示:

// 輸出全局變量 __dirname 的值

console.log( __dirname );

setTimeout(cb, ms)

setTimeout(cb, ms) 全局函數(shù)在指定的毫秒(ms)數(shù)后執(zhí)行指定函數(shù)(cb)。 實(shí)例

function printHello(){

console.log( "Hello, World!");

}

// 兩秒后執(zhí)行以上函數(shù)

setTimeout(printHello, 2000);

兩秒后輸出:

clearTimeout(t)

clearTimeout( t ) 全局函數(shù)用于停止一個(gè)之前通過(guò) setTimeout() 創(chuàng)建的定時(shí)器。

參數(shù) t 是通過(guò) setTimeout() 函數(shù)創(chuàng)建的定時(shí)器。

實(shí)例

function printHello(){

console.log( "Hello, World!");

}

// 兩秒后執(zhí)行以上函數(shù)

var t = setTimeout(printHello, 2000);

// 清除定時(shí)器

clearTimeout(t);

setInterval(cb, ms)

setInterval(cb, ms) 全局函數(shù)在指定的毫秒(ms)數(shù)后執(zhí)行指定函數(shù)(cb)。

可以使用 clearInterval(t) 函數(shù)來(lái)清除定時(shí)器。

setInterval() 方法會(huì)不停地調(diào)用函數(shù),直到 clearInterval() 被調(diào)用或窗口被關(guān)閉。

實(shí)例

function printHello(){

console.log( "Hello, World!");

}

// 兩秒后執(zhí)行以上函數(shù)

setInterval(printHello, 2000);

以上程序每隔兩秒就會(huì)輸出一次"Hello, World!",且會(huì)永久執(zhí)行下去,直到你按下 ctrl + c 按鈕。

console

console 用于提供控制臺(tái)標(biāo)準(zhǔn)輸出。

console.log([data][, …]) 向標(biāo)準(zhǔn)輸出流打印字符并以換行符結(jié)束。console.info([data][, …]) 這個(gè)命令與console.log差別并不大console.time(label) 輸出時(shí)間,表示計(jì)時(shí)開(kāi)始。console.timeEnd(label) 結(jié)束時(shí)間,表示計(jì)時(shí)結(jié)束。

實(shí)例

console.info("程序開(kāi)始執(zhí)行:");

var counter = 10;

console.log("計(jì)數(shù): %d", counter);

console.time("獲取數(shù)據(jù)");

//

// 執(zhí)行一些代碼

//

console.timeEnd('獲取數(shù)據(jù)');

console.info("程序執(zhí)行完畢。")

process

process 是一個(gè)全局變量,即 global 對(duì)象的屬性。

它用于描述當(dāng)前Node.js 進(jìn)程狀態(tài)的對(duì)象,提供了一個(gè)與操作系統(tǒng)的簡(jiǎn)單接口。

實(shí)例 Process 對(duì)象的常用的成員方法:exit 當(dāng)進(jìn)程準(zhǔn)備退出時(shí)觸發(fā)。

process.on('exit', function(code) {

// 以下代碼永遠(yuǎn)不會(huì)執(zhí)行

setTimeout(function() {

console.log("該代碼不會(huì)執(zhí)行");

}, 0);

console.log('退出碼為:', code);

});

console.log("程序執(zhí)行結(jié)束");

Process 屬性

stdout 標(biāo)準(zhǔn)輸出流。argv argv 屬性返回一個(gè)數(shù)組,由命令行執(zhí)行腳本時(shí)的各個(gè)參數(shù)組成。 它的第一個(gè)成員總是node,第二個(gè)成員是腳本文件名,其余成員是腳本文件的參數(shù)。execPath 返回執(zhí)行當(dāng)前腳本的 Node 二進(jìn)制文件的絕對(duì)路徑。platform 運(yùn)行程序所在的平臺(tái)系統(tǒng) ‘darwin’, ‘freebsd’, ‘linux’, ‘sunos’ 或 ‘win32’

// 輸出到終端

process.stdout.write("Hello World!" + "\n");

// 通過(guò)參數(shù)讀取

process.argv.forEach(function(val, index, array) {

console.log(index + ': ' + val);

});

// 獲取執(zhí)行路徑

console.log(process.execPath);

// 平臺(tái)信息

console.log(process.platform);

方法參考手冊(cè)

// 輸出當(dāng)前目錄

console.log('當(dāng)前目錄: ' + process.cwd());

// 輸出當(dāng)前版本

console.log('當(dāng)前版本: ' + process.version);

// 輸出內(nèi)存使用情況

console.log(process.memoryUsage());

常用工具

util 是一個(gè)Node.js 核心模塊,提供常用函數(shù)的集合。

使用方法如下:

const util = require('util');

util.callbackify

util.callbackify(original) 將 async 異步函數(shù)(或者一個(gè)返回值為 Promise 的函數(shù))轉(zhuǎn)換成遵循異常優(yōu)先的回調(diào)風(fēng)格的函數(shù)。

const util = require('util');

async function fn() {

return 'hello world';

}

const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {

if (err) throw err;

console.log(ret);

});

util.inherits

util.inherits(constructor, superConstructor) 是一個(gè)實(shí)現(xiàn)對(duì)象間原型繼承的函數(shù)。

var util = require('util');

function Base() {

this.name = 'base';

this.base = 1991;

this.sayHello = function() {

console.log('Hello ' + this.name);

};

}

Base.prototype.showName = function() {

console.log(this.name);

};

function Sub() {

this.name = 'sub';

}

util.inherits(Sub, Base);

var objBase = new Base();

objBase.showName();

objBase.sayHello();

console.log(objBase);

var objSub = new Sub();

objSub.showName();

//objSub.sayHello();

console.log(objSub);

我們定義了一個(gè)基礎(chǔ)對(duì)象 Base 和一個(gè)繼承自 Base 的 Sub。 Base 有三個(gè)在構(gòu)造函數(shù)內(nèi)定義的屬性和一個(gè)原型中定義的函數(shù),通過(guò)util.inherits 實(shí)現(xiàn)繼承。運(yùn)行結(jié)果如下:

注意:Sub 僅僅繼承了Base 在原型中定義的函數(shù),而構(gòu)造函數(shù)內(nèi)部創(chuàng)造的 base 屬性和 sayHello 函數(shù)都沒(méi)有被 Sub 繼承。

如果我們?nèi)サ?objSub.sayHello(); 這行的注釋?zhuān)瑢?huì)看到:

util.inspect

util.inspect(object,[showHidden],[depth],[colors]) 是一個(gè)將任意對(duì)象轉(zhuǎn)換 為字符串的方法。

showHidden 是一個(gè)可選參數(shù),如果值為 true,將會(huì)輸出更多隱藏信息。

var util = require('util');

function Person() {

this.name = 'byvoid';

this.toString = function() {

return this.name;

};

}

var obj = new Person();

console.log(util.inspect(obj));

console.log(util.inspect(obj, true));

util.isArray

如果給定的參數(shù) “object” 是一個(gè)數(shù)組返回 true,否則返回 false。

var util = require('util');

util.isArray([])

// true

util.isArray(new Array)

// true

util.isArray({})

// false

util.isRegExp(object)

如果給定的參數(shù) “object” 是一個(gè)正則表達(dá)式返回true,否則返回false。

var util = require('util');

util.isRegExp(/some regexp/)

// true

util.isRegExp(new RegExp('another regexp'))

// true

util.isRegExp({})

// false

util.isDate(object)

如果給定的參數(shù) “object” 是一個(gè)日期返回true,否則返回false。

var util = require('util');

util.isDate(new Date())

// true

util.isDate(Date())

// false (without 'new' returns a String)

util.isDate({})

// false

文件系統(tǒng)

Node 導(dǎo)入文件系統(tǒng)模塊(fs)語(yǔ)法如下所示:

var fs = require("fs")

異步和同步

異步的方法函數(shù)最后一個(gè)參數(shù)為回調(diào)函數(shù),回調(diào)函數(shù)的第一個(gè)參數(shù)包含了錯(cuò)誤信息(error)。

建議大家使用異步方法,比起同步,異步方法性能更高,速度更快,而且沒(méi)有阻塞。

實(shí)例 創(chuàng)建 input.txt 文件,內(nèi)容如下:

菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com

文件讀取實(shí)例

創(chuàng)建 file.js 文件, 代碼如下:

var fs = require("fs");

// 異步讀取

fs.readFile('input.txt', function (err, data) {

if (err) {

return console.error(err);

}

console.log("異步讀取: " + data.toString());

});

// 同步讀取

var data = fs.readFileSync('input.txt');

console.log("同步讀取: " + data.toString());

console.log("程序執(zhí)行完畢。");

打開(kāi)文件

語(yǔ)法

fs.open(path, flags[, mode], callback)

參數(shù)

path - 文件的路徑。 flags - 文件打開(kāi)的行為。flags 參數(shù)可以是以下值:

r 以讀取模式打開(kāi)文件。w 以寫(xiě)入模式打開(kāi)文件。r+/w+ 以讀寫(xiě)模式打開(kāi)文件。 mode - 設(shè)置文件模式(權(quán)限),文件創(chuàng)建默認(rèn)權(quán)限為 0666(可讀,可寫(xiě))。 callback - 回調(diào)函數(shù),帶有兩個(gè)參數(shù)如:callback(err, fd)。

實(shí)例 創(chuàng)建 file.js 文件,并打開(kāi) input.txt 文件進(jìn)行讀寫(xiě),代碼如下所示:

var fs = require("fs");

// 異步打開(kāi)文件

console.log("準(zhǔn)備打開(kāi)文件!");

fs.open('input.txt', 'r+', function(err, fd) {

if (err) {

return console.error(err);

}

console.log("文件打開(kāi)成功!");

});

獲取文件信息

語(yǔ)法 以下為通過(guò)異步模式獲取文件信息的語(yǔ)法格式:

fs.stat(path, callback)

參數(shù)

path - 文件路徑。callback - 回調(diào)函數(shù),帶有兩個(gè)參數(shù)如:(err, stats), stats 是 fs.Stats 對(duì)象。

fs.stat(path)執(zhí)行后,會(huì)將 stats 類(lèi)的實(shí)例返回給其回調(diào)函數(shù)??梢酝ㄟ^(guò) stats 類(lèi)中的提供方法判斷文件的相關(guān)屬性。例如判斷是否為文件:

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {

console.log(stats.isFile()); //true

})

實(shí)例

var fs = require("fs");

console.log("準(zhǔn)備打開(kāi)文件!");

fs.stat('input.txt', function (err, stats) {

if (err) {

return console.error(err);

}

console.log(stats);

console.log("讀取文件信息成功!");

// 檢測(cè)文件類(lèi)型

console.log("是否為文件(isFile) ? " + stats.isFile());

console.log("是否為目錄(isDirectory) ? " + stats.isDirectory());

});

寫(xiě)入文件

語(yǔ)法

fs.writeFile(file, data[, options], callback)

writeFile 直接打開(kāi)文件默認(rèn)是 w 模式,所以如果文件存在,該方法寫(xiě)入的內(nèi)容會(huì)覆蓋舊的文件內(nèi)容。 參數(shù)

file - 文件名或文件描述符。 data - 要寫(xiě)入文件的數(shù)據(jù),可以是 String(字符串) 或 Buffer(緩沖) 對(duì)象。 options - 該參數(shù)是一個(gè)對(duì)象,包含 {encoding, mode, flag}。默認(rèn)編碼為 utf8, 模式為 0666 , flag 為 ‘w’ callback - 回調(diào)函數(shù),回調(diào)函數(shù)只包含錯(cuò)誤信息參數(shù)(err),在寫(xiě)入失敗時(shí)返回。

實(shí)例 接下來(lái)我們創(chuàng)建 file.js 文件,代碼如下所示:

var fs = require("fs");

console.log("準(zhǔn)備寫(xiě)入文件");

fs.writeFile('input.txt', '我是通 過(guò)fs.writeFile 寫(xiě)入文件的內(nèi)容', function(err) {

if (err) {

return console.error(err);

}

console.log("數(shù)據(jù)寫(xiě)入成功!");

console.log("--------我是分割線(xiàn)-------------")

console.log("讀取寫(xiě)入的數(shù)據(jù)!");

fs.readFile('input.txt', function (err, data) {

if (err) {

return console.error(err);

}

console.log("異步讀取文件數(shù)據(jù): " + data.toString());

});

});

讀取文件

語(yǔ)法 以下為異步模式下讀取文件的語(yǔ)法格式:

fs.read(fd, buffer, offset, length, position, callback)

參數(shù)

fd - 通過(guò) fs.open() 方法返回的文件描述符。 buffer - 數(shù)據(jù)寫(xiě)入的緩沖區(qū)。 offset - 緩沖區(qū)寫(xiě)入的寫(xiě)入偏移量。 length - 要從文件中讀取的字節(jié)數(shù)。 position - 文件讀取的起始位置,如果 position 的值為 null,則會(huì)從當(dāng)前文件指針的位置讀取。 callback - 回調(diào)函數(shù),有三個(gè)參數(shù)err, bytesRead, buffer,err 為錯(cuò)誤信息, bytesRead 表示讀取的字節(jié)數(shù),buffer 為緩沖區(qū)對(duì)象。

實(shí)例 input.txt 文件內(nèi)容為:

菜鳥(niǎo)教程官網(wǎng)地址:www.runoob.com

file.js

var fs = require("fs");

var buf = new Buffer.alloc(1024);

console.log("準(zhǔn)備打開(kāi)已存在的文件!");

fs.open('input.txt', 'r+', function(err, fd) {

if (err) {

return console.error(err);

}

console.log("文件打開(kāi)成功!");

console.log("準(zhǔn)備讀取文件:");

fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

if (err){

console.log(err);

}

console.log(bytes + " 字節(jié)被讀取");

// 僅輸出讀取的字節(jié)

if(bytes > 0){

console.log(buf.slice(0, bytes).toString());

}

});

});

關(guān)閉文件

語(yǔ)法

fs.close(fd, callback)

參數(shù)

fd - 通過(guò) fs.open() 方法返回的文件描述符。 callback - 回調(diào)函數(shù),沒(méi)有參數(shù)。

實(shí)例 file.js

var fs = require("fs");

var buf = new Buffer.alloc(1024);

console.log("準(zhǔn)備打開(kāi)文件!");

fs.open('input.txt', 'r+', function(err, fd) {

if (err) {

return console.error(err);

}

console.log("文件打開(kāi)成功!");

console.log("準(zhǔn)備讀取文件!");

fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

if (err){

console.log(err);

}

// 僅輸出讀取的字節(jié)

if(bytes > 0){

console.log(buf.slice(0, bytes).toString());

}

// 關(guān)閉文件

fs.close(fd, function(err){

if (err){

console.log(err);

}

console.log("文件關(guān)閉成功");

});

});

});

截取文件

語(yǔ)法

fs.ftruncate(fd, len, callback)

參數(shù)

fd - 通過(guò) fs.open() 方法返回的文件描述符。 len - 文件內(nèi)容截取的長(zhǎng)度。 callback - 回調(diào)函數(shù),沒(méi)有參數(shù)。

實(shí)例 input.txt 文件內(nèi)容為:

site:www.runoob.com

file.js

var fs = require("fs");

var buf = new Buffer.alloc(1024);

console.log("準(zhǔn)備打開(kāi)文件!");

fs.open('input.txt', 'r+', function(err, fd) {

if (err) {

return console.error(err);

}

console.log("文件打開(kāi)成功!");

console.log("截取10字節(jié)內(nèi)的文件內(nèi)容,超出部分將被去除。");

// 截取文件

fs.ftruncate(fd, 10, function(err){

if (err){

console.log(err);

}

console.log("文件截取成功。");

console.log("讀取相同的文件");

fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

if (err){

console.log(err);

}

// 僅輸出讀取的字節(jié)

if(bytes > 0){

console.log(buf.slice(0, bytes).toString());

}

// 關(guān)閉文件

fs.close(fd, function(err){

if (err){

console.log(err);

}

console.log("文件關(guān)閉成功!");

});

});

});

});

刪除文件

語(yǔ)法

fs.unlink(path, callback)

參數(shù)

path - 文件路徑。 callback - 回調(diào)函數(shù),沒(méi)有參數(shù)。

實(shí)例 file.js

var fs = require("fs");

console.log("準(zhǔn)備刪除文件!");

fs.unlink('input.txt', function(err) {

if (err) {

return console.error(err);

}

console.log("文件刪除成功!");

});

創(chuàng)建目錄

語(yǔ)法

fs.mkdir(path[, options], callback)

參數(shù)

path - 文件路徑。 options 參數(shù)可以是:

recursive - 是否以遞歸的方式創(chuàng)建目錄,默認(rèn)為 false。mode - 設(shè)置目錄權(quán)限,默認(rèn)為 0777。 callback - 回調(diào)函數(shù),沒(méi)有參數(shù)。

實(shí)例 file.js

var fs = require("fs");

// tmp 目錄必須存在

console.log("創(chuàng)建目錄 /tmp/test/");

fs.mkdir("./tmp/test/",function(err){

if (err) {

return console.error(err);

}

console.log("目錄創(chuàng)建成功。");

});

讀取目錄

語(yǔ)法

fs.readdir(path, callback)

參數(shù)

path - 文件路徑。callback - 回調(diào)函數(shù),回調(diào)函數(shù)帶有兩個(gè)參數(shù)err, files,err 為錯(cuò)誤信息,files 為 目錄下的文件數(shù)組列表。

實(shí)例 file.js

var fs = require("fs");

console.log("查看 /tmp 目錄");

fs.readdir("/tmp/",function(err, files){

if (err) {

return console.error(err);

}

files.forEach( function (file){

console.log( file );

});

});

刪除目錄

語(yǔ)法

fs.rmdir(path, callback)

參數(shù)

path - 文件路徑。callback - 回調(diào)函數(shù),沒(méi)有參數(shù)。

實(shí)例 file.js

var fs = require("fs");

// 執(zhí)行前創(chuàng)建一個(gè)空的 /tmp/test 目錄

console.log("準(zhǔn)備刪除目錄 /tmp/test");

fs.rmdir("/tmp/test",function(err){

if (err) {

return console.error(err);

}

console.log("讀取 /tmp 目錄");

fs.readdir("/tmp/",function(err, files){

if (err) {

return console.error(err);

}

files.forEach( function (file){

console.log( file );

});

});

});

GET/POST 請(qǐng)求

在很多場(chǎng)景中,我們的服務(wù)器都需要跟用戶(hù)的瀏覽器打交道,如表單提交。

表單提交到服務(wù)器一般都使用 GET/POST 請(qǐng)求。

獲取 GET 請(qǐng)求內(nèi)容

由于GET請(qǐng)求直接被嵌入在路徑中,URL是完整的請(qǐng)求路徑,包括了?后面的部分,因此你可以手動(dòng)解析后面的內(nèi)容作為GET請(qǐng)求的參數(shù)。

node.js 中 url 模塊中的 parse 函數(shù)提供了這個(gè)功能。

var http = require('http');

var url = require('url');

var util = require('util');

http.createServer(function(req, res){

res.writeHead(200, {'Content-Type': 'text/plain'});

// 解析 url 參數(shù)

var params = url.parse(req.url, true).query;

res.write("網(wǎng)站名:" + params.name);

res.write("\n");

res.write("網(wǎng)站 URL:" + params.url);

res.end();

}).listen(3000);

獲取 POST 請(qǐng)求內(nèi)容

POST 請(qǐng)求的內(nèi)容全部的都在請(qǐng)求體中。

node.js 默認(rèn)是不會(huì)解析請(qǐng)求體的,當(dāng)你需要的時(shí)候,需要手動(dòng)來(lái)做。

var http = require('http');

var querystring = require('querystring');

var util = require('util');

http.createServer(function(req, res){

// 定義了一個(gè)post變量,用于暫存請(qǐng)求體的信息

var post = '';

// 通過(guò)req的data事件監(jiān)聽(tīng)函數(shù),每當(dāng)接受到請(qǐng)求體的數(shù)據(jù),就累加到post變量中

req.on('data', function(chunk){

post += chunk;

});

// 在end事件觸發(fā)后,通過(guò)querystring.parse將post解析為真正的POST請(qǐng)求格式,然后向客戶(hù)端返回。

req.on('end', function(){

post = querystring.parse(post);

res.end(util.inspect(post));

});

}).listen(3000);

Web 模塊

目前最主流的三個(gè)Web服務(wù)器是Apache、Nginx、IIS。

Web 應(yīng)用架構(gòu)

Client - 客戶(hù)端,一般指瀏覽器,瀏覽器可以通過(guò) HTTP 協(xié)議向服務(wù)器請(qǐng)求數(shù)據(jù)。 Server - 服務(wù)端,一般指 Web 服務(wù)器,可以接收客戶(hù)端請(qǐng)求,并向客戶(hù)端發(fā)送響應(yīng)數(shù)據(jù)。 Business - 業(yè)務(wù)層, 通過(guò) Web 服務(wù)器處理應(yīng)用程序,如與數(shù)據(jù)庫(kù)交互,邏輯運(yùn)算,調(diào)用外部程序等。 Data - 數(shù)據(jù)層,一般由數(shù)據(jù)庫(kù)組成。

使用 Node 創(chuàng)建 Web 服務(wù)器

Node.js 提供了 http 模塊,http 模塊主要用于搭建 HTTP 服務(wù)端和客戶(hù)端。

以下是演示一個(gè)最基本的 HTTP 服務(wù)器架構(gòu)(使用 8080 端口),創(chuàng)建server.js文件,代碼如下所示:

var http = require('http');

var fs = require('fs');

var url = require('url');

// 創(chuàng)建服務(wù)器

http.createServer( function (request, response) {

// 解析請(qǐng)求,包括文件名

var pathname = url.parse(request.url).pathname;

// 輸出請(qǐng)求的文件名

console.log("Request for " + pathname + " received.");

// 從文件系統(tǒng)中讀取請(qǐng)求的文件內(nèi)容

fs.readFile(pathname.substr(1), function (err, data) {

if (err) {

console.log(err);

// HTTP 狀態(tài)碼: 404 : NOT FOUND

// Content Type: text/html

response.writeHead(404, {'Content-Type': 'text/html'});

}else{

// HTTP 狀態(tài)碼: 200 : OK

// Content Type: text/html

response.writeHead(200, {'Content-Type': 'text/html'});

// 響應(yīng)文件內(nèi)容

response.write(data.toString());

}

// 發(fā)送響應(yīng)數(shù)據(jù)

response.end();

});

}).listen(8080);

// 控制臺(tái)會(huì)輸出以下信息

console.log('Server running at http://127.0.0.1:8080/');

執(zhí)行 server.js 程序: 打開(kāi)地址:

使用 Node 創(chuàng)建 Web 客戶(hù)端

client.js

var http = require('http');

// 用于請(qǐng)求的選項(xiàng)

var options = {

host: 'localhost',

port: '8080',

path: '/index.html'

};

// 處理響應(yīng)的回調(diào)函數(shù)

var callback = function(response){

// 不斷更新數(shù)據(jù)

var body = '';

response.on('data', function(data) {

body += data;

});

response.on('end', function() {

// 數(shù)據(jù)接收完成

console.log(body);

});

}

// 向服務(wù)端發(fā)送請(qǐng)求

var req = http.request(options, callback);

req.end();

在 server.js 啟動(dòng)的情況下,ctrl + shift + ` 新開(kāi)一個(gè)終端,執(zhí)行 client.js 文件: 客戶(hù)端請(qǐng)求信息,執(zhí)行 server.js 的控制臺(tái)輸出:

Express 框架

使用 Express 可以快速地搭建一個(gè)完整功能的網(wǎng)站。

安裝

cnpm install express

cnpm install body-parser

cnpm install cookie-parser

cnpm install multer

以下幾個(gè)重要的模塊是需要與 express 框架一起安裝的:

body-parser - 用于處理 JSON, Raw, Text 和 URL 編碼的數(shù)據(jù)。 cookie-parser - 這就是一個(gè)解析Cookie的工具。通過(guò)req.cookies可以取到傳過(guò)來(lái)的cookie,并把它們轉(zhuǎn)成對(duì)象。 multer - 用于處理 enctype=“multipart/form-data”(設(shè)置表單的MIME編碼)的表單數(shù)據(jù)。

第一個(gè) Express 框架實(shí)例

以下實(shí)例中我們引入了 express 模塊,并在客戶(hù)端發(fā)起請(qǐng)求后,響應(yīng) “Hello World” 字符串。

創(chuàng)建 express_demo.js 文件,代碼如下所示:

var express = require('express');

var app = express();

app.get('/', function (req, res) {

res.send('Hello World');

})

var server = app.listen(8081, '127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

請(qǐng)求和響應(yīng)

Express 應(yīng)用使用回調(diào)函數(shù)的參數(shù): request 和 response 對(duì)象來(lái)處理請(qǐng)求和響應(yīng)的數(shù)據(jù)。

app.get('/', function (req, res) {

// --

})

Request 對(duì)象 - request 對(duì)象表示 HTTP 請(qǐng)求,包含了請(qǐng)求查詢(xún)字符串,參數(shù),內(nèi)容,HTTP 頭部等屬性。Response 對(duì)象 - response 對(duì)象表示 HTTP 響應(yīng),即在接收到請(qǐng)求時(shí)向客戶(hù)端發(fā)送的 HTTP 響應(yīng)數(shù)據(jù)。

路由

路由決定了由誰(shuí)(指定腳本)去響應(yīng)客戶(hù)端請(qǐng)求。

在HTTP請(qǐng)求中,我們可以通過(guò)路由提取出請(qǐng)求的URL以及GET/POST參數(shù)。

express_demo2.js

var express = require('express');

var app = express();

// 主頁(yè)輸出 "Hello World"

app.get('/', function (req, res) {

console.log("主頁(yè) GET 請(qǐng)求");

res.send('Hello GET');

})

// POST 請(qǐng)求

app.post('/', function (req, res) {

console.log("主頁(yè) POST 請(qǐng)求");

res.send('Hello POST');

})

// /del_user 頁(yè)面響應(yīng)

app.get('/del_user', function (req, res) {

console.log("/del_user 響應(yīng) DELETE 請(qǐng)求");

res.send('刪除頁(yè)面');

})

// /list_user 頁(yè)面 GET 請(qǐng)求

app.get('/list_user', function (req, res) {

console.log("/list_user GET 請(qǐng)求");

res.send('用戶(hù)列表頁(yè)面');

})

// 對(duì)頁(yè)面 abcd, abxcd, ab123cd, 等響應(yīng) GET 請(qǐng)求

app.get('/ab*cd', function(req, res) {

console.log("/ab*cd GET 請(qǐng)求");

res.send('正則匹配');

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

靜態(tài)文件

你可以使用express.static中間件來(lái)設(shè)置靜態(tài)文件路徑。例如,如果你將圖片, CSS, JavaScript 文件放在 public 目錄下,你可以這么寫(xiě):

app.use('/public', express.static('public'));

創(chuàng)建文件夾public/images,放入圖片logo.png express_demo3.js

var express = require('express');

var app = express();

app.use('/public', express.static('public'));

app.get('/', function (req, res) {

res.send('Hello World');

})

var server = app.listen(8081, function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

訪問(wèn)網(wǎng)頁(yè):http://127.0.0.1:8081/public/images/logo.png

得到logo.png:

GET 方法

在表單中通過(guò) GET 方法提交兩個(gè)參數(shù),我們可以使用 server.js 文件內(nèi)的 process_get 路由器來(lái)處理輸入:

index.html 文件代碼:

First Name:

Last Name:

server.js 文件代碼:

var express = require('express');

var app = express();

app.use('/public', express.static('public'));

app.get('/index.html', function (req, res) {

res.sendFile( __dirname + "/" + "index.html" );

})

app.get('/process_get', function (req, res) {

// 輸出 JSON 格式

var response = {

"first_name":req.query.first_name,

"last_name":req.query.last_name

};

console.log(response);

res.end(JSON.stringify(response));

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

POST 方法

在表單中通過(guò) POST 方法提交兩個(gè)參數(shù),我們可以使用 server.js 文件內(nèi)的 process_post 路由器來(lái)處理輸入:

index.html 文件代碼:

First Name:

Last Name:

server.js 文件代碼:

var express = require('express');

var app = express();

var bodyParser = require('body-parser');

// 創(chuàng)建 application/x-www-form-urlencoded 編碼解析

var urlencodedParser = bodyParser.urlencoded({ extended: false })

app.use('/public', express.static('public'));

app.get('/index.html', function (req, res) {

res.sendFile( __dirname + "/" + "index.html" );

})

app.post('/process_post', urlencodedParser, function (req, res) {

// 輸出 JSON 格式

var response = {

"first_name":req.body.first_name,

"last_name":req.body.last_name

};

console.log(response);

res.end(JSON.stringify(response));

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

文件上傳

創(chuàng)建一個(gè)用于上傳文件的表單,使用 POST 方法,表單 enctype 屬性設(shè)置為 multipart/form-data。

index.html 文件代碼:

文件上傳表單

文件上傳:

選擇一個(gè)文件上傳:


server.js 文件代碼:

var express = require('express');

var app = express();

var fs = require("fs");

var bodyParser = require('body-parser');

var multer = require('multer');

app.use('/public', express.static('public'));

app.use(bodyParser.urlencoded({ extended: false }));

app.use(multer({ dest: '/tmp/'}).array('image'));

app.get('/index.html', function (req, res) {

res.sendFile( __dirname + "/" + "index.html" );

})

app.post('/file_upload', function (req, res) {

console.log(req.files[0]); // 上傳的文件信息

var des_file = __dirname + "/" + req.files[0].originalname;

fs.readFile( req.files[0].path, function (err, data) {

fs.writeFile(des_file, data, function (err) {

if( err ){

console.log( err );

}else{

response = {

message:'File uploaded successfully',

filename:req.files[0].originalname

};

}

console.log( response );

res.end( JSON.stringify( response ) );

});

});

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

Cookie 管理

使用中間件向 Node.js 服務(wù)器發(fā)送 cookie 信息,以下代碼輸出了客戶(hù)端發(fā)送的 cookie 信息: express_cookie.js 文件代碼:

// express_cookie.js 文件

var express = require('express')

var cookieParser = require('cookie-parser')

var util = require('util');

var app = express()

app.use(cookieParser())

app.get('/', function(req, res) {

console.log("Cookies: " + util.inspect(req.cookies));

})

app.listen(8081)

訪問(wèn) http://127.0.0.1:8081,并查看終端信息:

RESTful API

REST即表述性狀態(tài)傳遞(英文:Representational State Transfer)。

REST 通常使用 JSON 數(shù)據(jù)格式。

以下為 REST 基本架構(gòu)的四個(gè)方法:

GET - 用于獲取數(shù)據(jù)。 PUT - 用于更新或添加數(shù)據(jù)。 DELETE - 用于刪除數(shù)據(jù)。 POST - 用于添加數(shù)據(jù)。

創(chuàng)建 RESTful

首先,創(chuàng)建一個(gè) json 數(shù)據(jù)資源文件 users.json:

{

"user1" : {

"name" : "mahesh",

"password" : "password1",

"profession" : "teacher",

"id": 1

},

"user2" : {

"name" : "suresh",

"password" : "password2",

"profession" : "librarian",

"id": 2

},

"user3" : {

"name" : "ramesh",

"password" : "password3",

"profession" : "clerk",

"id": 3

}

}

獲取用戶(hù)列表:

以下代碼,我們創(chuàng)建了 RESTful API listUsers,用于讀取用戶(hù)的信息列表, server.js 文件代碼如下所示:

var express = require('express');

var app = express();

var fs = require("fs");

app.get('/listUsers', function (req, res) {

fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {

console.log( data );

res.end( data );

});

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

在瀏覽器中訪問(wèn) http://127.0.0.1:8081/listUsers,結(jié)果如下所示:

添加用戶(hù)

以下代碼,我們創(chuàng)建了 RESTful API addUser, 用于添加新的用戶(hù)數(shù)據(jù),server.js 文件代碼如下所示:

var express = require('express');

var app = express();

var fs = require("fs");

//添加的新用戶(hù)數(shù)據(jù)

var user = {

"user4" : {

"name" : "mohit",

"password" : "password4",

"profession" : "teacher",

"id": 4

}

}

app.get('/addUser', function (req, res) {

// 讀取已存在的數(shù)據(jù)

fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {

data = JSON.parse( data );

data["user4"] = user["user4"];

console.log( data );

res.end( JSON.stringify(data));

});

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

顯示用戶(hù)詳情

我們創(chuàng)建了 RESTful API :id(用戶(hù)id), 用于讀取指定用戶(hù)的詳細(xì)信息,server.js 文件代碼如下所示:

var express = require('express');

var app = express();

var fs = require("fs");

app.get('/:id', function (req, res) {

// 首先我們讀取已存在的用戶(hù)

fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {

data = JSON.parse( data );

var user = data["user" + req.params.id]

console.log( user );

res.end( JSON.stringify(user));

});

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

刪除用戶(hù)

我們創(chuàng)建了 RESTful API deleteUser, 用于刪除指定用戶(hù)的詳細(xì)信息,以下實(shí)例中,用戶(hù) id 為 2,server.js 文件代碼如下所示:

var express = require('express');

var app = express();

var fs = require("fs");

var id = 2;

app.get('/deleteUser', function (req, res) {

// First read existing users.

fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {

data = JSON.parse( data );

delete data["user" + id];

console.log( data );

res.end( JSON.stringify(data));

});

})

var server = app.listen(8081,'127.0.0.1',function () {

var host = server.address().address

var port = server.address().port

console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

多進(jìn)程

Node 提供了 child_process 模塊來(lái)創(chuàng)建子進(jìn)程,方法有:

exec() 方法

讓我們創(chuàng)建兩個(gè) js 文件 support.js 和 master.js。

support.js 文件代碼:

console.log("進(jìn)程 " + process.argv[2] + " 執(zhí)行。" );

master.js 文件代碼:

const fs = require('fs');

const child_process = require('child_process');

for(var i=0; i<3; i++) {

var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {

if (error) {

console.log(error.stack);

console.log('Error code: '+error.code);

console.log('Signal received: '+error.signal);

}

console.log('stdout: ' + stdout);

console.log('stderr: ' + stderr);

});

workerProcess.on('exit', function (code) {

console.log('子進(jìn)程已退出,退出碼 '+code);

});

}

柚子快報(bào)激活碼778899分享:Node.js---菜鳥(niǎo)教程

http://yzkb.51969.com/

好文鏈接

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/15795193.html

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

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄