Node.js 學習之路

1、建立第一個簡單應用

1.建立服務器(在當前目錄下新建server.js)

var http =  require('http');
http.createServer(function(request,response){
    //發送http頭部
    //http請求值狀態:200OK
    //內容類型:text/plain
    response.writeHead(200,{'Content-Type':'text/plain'});
    
    //發送響應數據 helloword
    response.end('hello word\n');
    
}).listen(8888);//端口8888
console.log('Server running at http://127.0.0.1:8888/');

2.打開打開瀏覽器訪問 http://127.0.0.1:8888/查看狀態

瀏覽器中響應helloword及建立成功node

2、npm的使用

(說明)
-容許用戶從NPM服務器下載別人編寫的第三方包到本地使用。
-容許用戶從NPM服務器下載並安裝別人編寫的命令行程序到本地使用。
-容許用戶將本身編寫的包或命令行程序上傳到NPM服務器供別人使用。es6

(查看是否安裝)express

$ node -v

(npm舊版本升級)npm

$npm install npm -g

(使用 npm 命令安裝模塊)編程

$ npm install <Module Name>

好比安裝node的框架模塊
$ npm install express

安裝好以後,express 包就放在了工程目錄下的 node_modules 目錄中,所以在代碼中只須要經過 require('express') 的方式就好,無需指定第三方包路徑。
var express = require('express');
  • 卸載模塊($ npm uninstall express)
  • 更新模塊($ npm update express)
  • 搜索模塊($ npm search express)
  • 建立模塊($ npm create express)

3、Node.js REPL(交互式解釋器)

Node 自帶了交互式解釋器,能夠執行如下任務: 讀取 - 讀取用戶輸入,解析輸入了Javascript 數據結構並存儲在內存中。 執行 -
執行輸入的數據結構 打印 - 輸出結果 循環 - 循環操做以上步驟直到用戶兩次按下 ctrl-c 按鈕退出。 Node
的交互式解釋器能夠很好的調試 Javascript 代碼。

輸入 $ node 命令便可json

表達式運算數組

$ node瀏覽器

1 +4 5
5 / 2
2.5
3 * 6 18
4 - 1 3
1 + ( 2 * 3 ) - 4 3

下劃線(_)變量緩存

你可使用下劃線(_)獲取表達式的運算結果: $ node服務器

var x = 10 undefined
var y = 20 undefined
x + y 30
var sum = _ undefined
console.log(sum) 30 undefined

4、pepl命令

ctrl + c - 退出當前終端。 ctrl + c 按下兩次 - 退出 Node REPL。 ctrl + d - 退出 Node
REPL. 向上/向下 鍵 - 查看輸入的歷史命令 tab 鍵 - 列出當前命令 .help - 列出使用命令 .break -
退出多行表達式 .clear - 退出多行表達式 .save filename - 保存當前的 Node REPL 會話到指定文件
.load filename - 載入當前 Node REPL 會話的文件內容。

5、Node.js回調函數

Node 使用了大量的回調函數,Node 全部 API 都支持回調函數。
例如,咱們能夠一邊讀取文件,一邊執行其餘命令,在文件讀取完成後,咱們將文件內容做爲回調函數的參數返回。這樣在執行代碼時就沒有阻塞或等待文件
I/O 操做。這就大大提升了 Node.js 的性能,能夠處理大量的併發請求。

阻塞代碼實例(同步執行):
-建立txt文件做爲讀取文件a.txt。
-建立main.js文件,代碼以下:

var fs = require('fs');//引入fs模塊
var data = fs.readFileSync("a.txt");
console.log(data.toString());
console.log("end");

非阻塞代碼實例(異步執行):
-

var fs = require("fs");//引入fs模塊
fs.readFile("a.txt",function(err,data){
    if(err){
        return console.error(err);
    }
console.log(data.toString())
})

console.log("end");

6、事件循環

實例:
建立main.js文件代碼:
//引入events模塊
var events = require("events");
//建立eventEmitter對象
Var eventEmitter = new events.EventEmitter();

//建立事件處理程序
var connectHandler = function conected(){

console.log("connect ok");
//觸發data_received 事件
eventEmitter.emit("data_received");

}

//綁定connection事件處理程序
eventEimtter.on('connection',connectHandler);

// 使用匿名函數綁定 data_received 事件
eventEmitter.on('data_received', function(){
console.log('數據接收成功。');
});

// 觸發 connection 事件
eventEmitter.emit('connection');

console.log("end!");

7、Node.js EventEmitter

Node.js 全部的異步 I/O 操做在完成時都會發送一個事件到事件隊列。
Node.js裏面的許多對象都會分發事件:一個net.Server對象會在每次有新鏈接時分發一個事件,
一個fs.readStream對象會在文件被打開的時候發出一個事件。 全部這些產生事件的對象都是 events.EventEmitter
的實例。

events 模塊只提供了一個對象: events.EventEmitter。EventEmitter 的核心就是事件觸發與事件監聽器功能的封裝。
你能夠經過require("events");來訪問該模塊。
//引入events模塊
var events = require("events");
//建立EventEmitter對象
var eventEmitter = new events.EventEmiter();
EventEmitter 對象若是在實例化時發生錯誤,會觸發 error 事件。當添加新的監聽器時,newListener
事件會觸發,當監聽器被移除時,removeListener 事件被觸發。

EventEmitter簡單介紹

在Nodejs中,異步的I/O 操做在完成時會觸發事件隊列中的具體事件。這裏的主要緣由是這些對象本質上是經過繼承EventEmitter來實現對事件的處理和回調,如文件的file讀寫等。(這裏的事件與DOM樹上事件不一樣,不存在事件冒泡和捕獲的狀況。)咱們也可讓自定義的對象經過繼承EventEmitter來讓其走觀察者模式(事件監聽與觸發),主要經過EventEmitter的on和emit這些方法來構成。也有更爲具體的API。如emitter.once(event,listener)添加一次性 listener(這個 listener 只會被觸發一次,觸發完成後就被刪除)。

咱們用一個簡單的例子說明 EventEmitter 的用法:

events.js文件

//EventEmitter是events模塊中的一個對象。
var EventEmitter = require('events').EventEmitter;
//實例化一個eventEmitter
var event = new EventEmitter();
//綁定個自定義事件,即回調函數
event.on('some_event',function(){
    console.log('some_event事件觸發');
})
//3s後經過emit觸發這個事件。
setTimout(function(){
    event.emit('some_event');
},3000);

大體流程:
引用events包-->調用EventEmitter包-->實例化-->綁定自定義事件-->emit觸發事件

運行這段代碼,1 秒後控制檯輸出了 'some_event 事件觸發'。其原理是 event 對象註冊了事件 some_event
的一個監聽器,而後咱們經過 setTimeout 在 3000 毫秒之後向 event 對象發送事件
some_event,此時會調用some_event 的監聽器。

EventEmitter主要API

emitter.on('event',listener)//註冊一個事件
emitter.once('event',listener)//註冊一個一次性事件,觸發後即銷燬。
emitter.removeListener(event, listener) 在時間隊列中移除某一個事件。
emitter.removeAllListeners([event]) 刪除整個事件隊列,或多個事件。
emitter.listeners(event) 返回某些事件 emitter.emit(event, [arg1], [arg2], […]) 觸發事件,可傳入具體參數

8、Buffer(緩衝區)

JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。 但在處理像TCP流或文件流時,必須使用到二進制數據。所以在
Node.js中,定義了一個 Buffer 類,該類用來建立一個專門存放二進制數據的緩存區。 在 Node.js 中,Buffer 類是隨
Node 內核一塊兒發佈的核心庫。Buffer 庫爲 Node.js 帶來了一種存儲原始數據的方法,可讓 Node.js
處理二進制數據,每當須要在 Node.js 中處理I/O操做中移動的數據時,就有可能使用 Buffer 庫。原始數據存儲在 Buffer
類的實例中。一個 Buffer 相似於一個整數數組,但它對應於 V8 堆內存以外的一塊原始內存。

建立buffer類

實例:
建立長度爲10字節的buffer實例
var buf = new Buffer(10);

經過數組建立buffer實例
var buf= new Buffer([1,2,3,4,5]);

經過字符串來建立buffer實例
var buf = new Buffer('www.lipengpeng.com',"utf-8");

寫入緩衝區

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

參數 參數描述以下: string - 寫入緩衝區的字符串。 offset - 緩衝區開始寫入的索引值,默認爲 0 。
length -寫入的字節數,默認爲 buffer.length encoding - 使用的編碼。默認爲 'utf8' 。
返回值.返回實際寫入的大小。若是 buffer 空間不足, 則只會寫入部分字符串。

實例:

var buff = new Buffer(15);
var len = buff.write('lipengpeng.com');
console.log(len);//返回寫入的大小 result:14

緩衝區讀取數據

讀取node緩衝區語法:

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

參數:
參數描述以下:

  • encoding - 使用的編碼。默認爲 'utf8' 。
  • start - 指定開始讀取的索引位置,默認爲 0。
  • end -結束位置,默認爲緩衝區的末尾。

返回值
解碼緩衝區數據並使用指定的編碼返回字符串。
實例:

buf = new Buffer(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)); // 輸出: abcde
console.log( buf.toString('utf8',0,5));// 輸出: abcde
console.log( buf.toString(undefined,0,5));// 使用 'utf8' 編碼,

並輸出: abcde

將buffer轉爲json對象

語法
將node buffer轉爲json對象語法格式
buff.toJSON()//fanhui json對象
實例:
var buff = new Buffer("www.lipengpeng.com");
var json = buff.toJSON(json);
結果:

{ type: 'Buffer',data:[ 119, 119,119, 46,108, 105, 112, 101,  110, 103, 112, 101, 110,103,46,99,111,109 ] }

緩衝區合併

Buffer.concat(list[, totalLength])
參數: list - 用於合併的 Buffer 對象數組列表。 totalLength - 指定合併後Buffer對象的總長度。 返回值:
返回一個多個成員合併的新 Buffer 對象。

實例:

var buffer1 = new Buffer('www. ');
var buffer2 = new Buffer('lipengpeng.com');
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 內容: " + buffer3.toString());

緩衝區比較

buf.compare(otherBuffer); 參數:otherBuffer - 與 buf 對象比較的另一個 Buffer 對象。
返回一個數字,表示 buf 在 otherBuffer 以前,以後或相同。

var buffer1 = new Buffer('ABC');
var buffer2 = new Buffer('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 + "以後");
}

拷貝緩衝區

buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]);
參數描述以下:

targetBuffer - 要拷貝的 Buffer 對象。
targetStart - 數字, 可選, 默認: 0
sourceStart - 數字, 可選, 默認: 0
sourceEnd - 數字, 可選, 默認: buffer.length

實例
var buffer1 = new Buffer('ABC');
//拷貝一個緩衝區
var buffer2 = new Buffer(3);
buffer1.copy(buffer2);

9、Steam流

Node.js,Stream 有四種流類型:

  • Readable - 可讀操做。
  • Writable - 可寫操做。
  • Duplex - 可讀可寫操做.
  • Transform - 操做被寫入數據,而後讀出結果。

全部的 Stream 對象都是 EventEmitter 的實例。經常使用的事件有:

  • data - 當有數據可讀時觸發。
  • end - 沒有更多的數據可讀時觸發。
  • error - 在接收和寫入過程當中發生錯誤時觸發。
  • finish - 全部數據已被寫入到底層系統時觸發。

實例:流中讀取數據

建立一個txt文件 test.txt
建立js文件,main.js

var datas='';
//fs模塊用於對系統文件及目錄進行讀寫操做
var fs = require('fs');
//建立可讀流
var readerStream = fs.createReaderStream(test.txt');
//如文件中有中文字符請設置編碼
readerStream.setEncoding('utf8');
//處理事件流
readerStream.on('data',function(res){
    data+=res;
    console.log(data)
});

實例:寫入流

var fs = require('fs');
    var data="lipengpeng.com";
    //建立一個可寫入的流,寫入到文件write.txt;
    var writerStream = fs.createWriteStream('write.txt');
    //使用utf_8寫入數據
    writerStream.write(data,'utf8');
    // 標記文件末尾
    writerStream.end();
   writerStream.on('finish', function() {
        console.log("ok");
    });

實例:複製流

var fs = require('fs');
     //寫入流
    var writerStream = fs.createWriteStream('write.txt');
    //讀取流
    var readerStream = fs.createReadStream('read.txt');
   //經過pipe讀取流流入寫入流
    readerStream.pipe(writerStream);
    console.log('ok!');

10、模塊系統

Node.js 提供了exports 和 require 兩個對象,其中 exports 是模塊公開的接口,require
用於從外部獲取一個模塊的接口,即所獲取模塊的 exports 對象。
nodejs中模塊化編程最主要的一個特徵就是經常能夠在不少js文件看到require(),也就是引入其餘的js文件,很是相似與其餘語言中的import或include。同時若是想要require('A'),那麼在A文件中必需要使用exports這個關鍵字代表要導出什麼變量或函數。
//引入同一目錄下的name.js  
var name = require('./name');  
  
//使用name.js中的變量  
console.log(name.name1);  
//調用name.js中的函數  
name.getName();  


 //變量  
 var name1 = "Jack";  
 //函數  
 function getName() {  
     console.log("Mary");  
 }  
      
 //分別導出變量和函數  
 module.exports.name1 = name1;  
 module.exports.getName = getName;  

簡化以上代碼:

//name.js
var name1="jack";
function getName(){
    console.log("Mary");
}
//導出變量和函數
module.exports={
    name1,//es6語法(name1:name1)
    getName
}

//引入變量和函數
var name = require('./name');  
console.log(name.name1);//jack
name.getName();//Mary
相關文章
相關標籤/搜索