node.js基礎回顧

Node.js 應用是由哪幾部分組成的:html

  • 引入 required 模塊:咱們可使用 require 指令來載入 Node.js 模塊。
  • 建立服務器:服務器能夠監聽客戶端的請求,相似於 Apache 、Nginx 等 HTTP 服務器。
  • 接收請求與響應請求: 服務器很容易建立,客戶端可使用瀏覽器或終端發送 HTTP 請求,服務器接收請求後返回響應數據。

建立簡單Node.js 應用示例
步驟一:引入 required 模塊node

var http = require("http");

步驟二:建立服務器web

var http = require('http');
http.createServer(function (request, response) {
// 發送 HTTP 頭部 
// HTTP 狀態值: 200 : OK
// 內容類型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 發送響應數據 "Hello World"
response.end('Hello World\n');
}).listen(8888);
// 終端打印以下信息
console.log('Server running at http://127.0.0.1:8888/');

步驟三:使用 node 命令執行以上的代碼:正則表達式

node server.js
Server running at http://127.0.0.1:8888/

步驟四:打開瀏覽器訪問 http://127.0.0.1:8888/,你會看到一個寫着 "Hello World"的網頁。

分析Node.js 的 HTTP 服務器:設計模式

  • 第一行請求(require)Node.js 自帶的 http 模塊,而且把它賦值給 http 變量。
  • 接下來咱們調用 http 模塊提供的函數: createServer 。這個函數會返回 一個對象,這個對象有一個叫作 listen 的方法,這個方法有一個數值參數, 指定這個 HTTP 服務器監聽的端口號。

Node.js REPL(交互式解釋器)
Node 自帶了交互式解釋器,能夠執行如下任務:數組

  • 讀取 - 讀取用戶輸入,解析輸入了Javascript 數據結構並存儲在內存中。
  • 執行 - 執行輸入的數據結構
  • 打印 - 輸出結果
  • 循環 - 循環操做以上步驟直到用戶兩次按下 ctrl-c 按鈕退出。

Node 的交互式解釋器能夠很好的調試 Javascript 代碼。瀏覽器

REPL 命令
ctrl + c - 退出當前終端。
ctrl + c 按下兩次 - 退出 Node REPL。
ctrl + d - 退出 Node REPL.
向上/向下 鍵 - 查看輸入的歷史命令
tab 鍵 - 列出當前命令緩存

.help - 列出使用命令
.break - 退出多行表達式
.clear - 退出多行表達式
.save filename - 保存當前的 Node REPL 會話到指定文件
.load filename - 載入當前 Node REPL 會話的文件內容。
按下兩次 ctrl + c 鍵就能退出 REPL

Node.js 回調函數服務器

  • 阻塞代碼
    建立一個文件 input.txt ,內容自定義。
    建立 main.js 文件, 代碼以下:
var fs = require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程序執行結束!");
  • 非阻塞代碼
    建立一個文件 input.txt ,內容自定義。
    建立 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("程序執行結束!");

第一個實例(阻塞)在文件讀取完後才執行完程序。 第二個實例(非阻塞)不須要等待文件讀取完,這樣就能夠在讀取文件時同時執行接下來的代碼,大大提升了程序的性能。阻塞是按順序執行的,而非阻塞是不須要按順序的,因此若是須要處理回調函數的參數,咱們就須要寫在回調函數內。數據結構

Node.js 事件循環

  • Node.js 是單進程單線程應用程序,可是由於 V8 引擎提供的異步執行回調接口,經過這些接口能夠處理大量的併發,因此性能很是高。
  • Node.js 幾乎每個 API 都是支持回調函數的。
  • Node.js 基本上全部的事件機制都是用設計模式中觀察者模式實現。
  • Node.js 單線程相似進入一個while(true)的事件循環,直到沒有事件觀察者退出,每一個異步事件都生成一個事件觀察者,若是有事件發生就調用該回調函數.

Node.js EventEmitter
EventEmitter 類
events 模塊只提供了一個對象: events.EventEmitter。EventEmitter 的核心就是***事件觸發與事件監聽器功能的封裝***。能夠經過require(「events」);來訪問該模塊。

// 引入 events 模塊
var events = require('events');
// 建立 eventEmitter 對象
var eventEmitter = new events.EventEmitter();

Node.js Buffer(緩衝區)
JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。但在處理像TCP流或文件流時,必須使用到二進制數據。所以在 Node.js中,定義了一個 Buffer 類,該類用來***建立一個專門存放二進制數據的緩存區***。一個 Buffer 相似於一個整數數組,它對應於 V8 堆內存以外的一塊原始內存。

Node.js Stream(流)
Stream 是一個抽象接口,Node 中有不少對象實現了這個接口。例如,對http 服務器發起請求的request 對象就是一個 Stream,還有stdout(標準輸出)。Node.js,Stream 有四種流類型:
Readable - 可讀操做。
Writable - 可寫操做。
Duplex - 可讀可寫操做.
Transform - 操做被寫入數據,而後讀出結果。
全部的 Stream 對象都是 EventEmitter 的實例。經常使用的事件有:
data - 當有數據可讀時觸發。
end - 沒有更多的數據可讀時觸發。
error - 在接收和寫入過程當中發生錯誤時觸發。
finish - 全部數據已被寫入到底層系統時觸發。

Node.js模塊系統
一個 Node.js 文件就是一個模塊,這個文件多是JavaScript 代碼、JSON 或者編譯過的C/C++ 擴展。

//hello.js 模塊
function Hello() { 
    var name; 
    this.setName = function(thyName) { 
        name = thyName; 
    }; 
    this.sayHello = function() { 
        console.log('Hello ' + name); 
    }; 
}; 
module.exports = Hello;

//main.js 調用hello.js模塊(hello.js和node.js是在兩個不一樣的js文件中)
var Hello = require('./hello'); 
hello = new Hello(); 
hello.setName('BYVoid'); 
hello.sayHello();

Node.js 函數
在JavaScript中,一個函數能夠做爲另外一個函數的參數。咱們能夠先定義一個函數,而後傳遞,也能夠在傳遞參數的地方直接定義函數。
Node.js中函數的使用與Javascript相似。

//把 say 函數做爲execute函數的第一個變量進行了傳遞
function say(word) {
  console.log(word);
}
function execute(someFunction, value) {
  someFunction(value);
}
execute(say, "Hello");

匿名函數
咱們能夠把一個函數做爲變量傳遞。可是咱們不必定要繞這個"先定義,再傳遞"的圈子,咱們能夠直接在另外一個函數的括號中定義和傳遞這個函數:

//execute 接受第一個參數的地方直接定義了咱們準備傳遞給 execute 的函數。用這種方式,咱們甚至不用給這個函數起名字,這也是爲何它被叫作匿名函數 。 
function execute(someFunction, value) {
  someFunction(value);
}
execute(function(word){ console.log(word) }, "Hello");

函數傳遞是如何讓HTTP服務器工做的

//咱們向 createServer 函數傳遞了一個匿名函數。 
var http = require("http");
http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

Node.js 全局對象
在瀏覽器 JavaScript 中,一般 window 是全局對象, 而 Node.js 中的全局對象是 global

  • __filename 表示當前正在執行的腳本的文件名。它將輸出文件所在位置的絕對路徑,且和命令行參數所指定的文件名不必定相同。
  • __dirname 表示當前執行腳本所在的目錄。
  • setTimeout(cb, ms) 全局函數在指定的毫秒(ms)數後執行指定函數(cb)。:setTimeout() 只執行一次指定函數。返回一個表明定時器的句柄值。
    -clearTimeout( t ) 全局函數用於中止一個以前經過 setTimeout() 建立的定時器。 參數 t 是經過 setTimeout() 函數建立的定時器。
  • setInterval(cb, ms) 全局函數在指定的毫秒(ms)數後執行指定函數(cb)。返回一個表明定時器的句柄值。可使用 clearInterval(t) 函數來清除定時器。setInterval() 方法會不停地調用函數,直到 clearInterval() 被調用或窗口被關閉。
  • console 用於提供控制檯標準輸出
  • process 是一個全局變量,即 global 對象的屬性。它用於描述當前Node.js 進程狀態的對象,提供了一個與操做系統的簡單接口。

Node.js 經常使用工具

  • util.inherits(constructor, superConstructor)是一個實現對象間原型繼承 的函數。僅僅繼承了原型中定義的函數,而構造函數內部創造的屬 性和 函數都沒有繼承。
  • util.inspect(object,[showHidden],[depth],[colors])是一個將任意對象轉換 爲字符串的方法,一般用於調試和錯誤輸出。
  • util.isArray(object)若是給定的參數 「object」 是一個數組返回true,不然返回false。
  • util.isRegExp(object)若是給定的參數 「object」 是一個正則表達式返回true,不然返回false。
  • util.isDate(object)若是給定的參數 「object」 是一個日期返回true,不然返回false。
  • util.isError(object)若是給定的參數 「object」 是一個錯誤對象返回true,不然返回false。

Node.js 文件系統
異步的 fs.readFile() 和同步的 fs.readFileSync()。

  • 異步模式下打開文件:fs.open(path, flags[, mode], callback)
  • 異步模式下獲取文件信息:fs.stat(path, callback)
  • 異步模式下寫入文件:fs.writeFile(file, data[, options], callback)
  • 異步模式下讀取文件:fs.read(fd, buffer, offset, length, position, callback)
  • 異步模式下關閉文件:fs.close(fd, callback)
  • 異步模式下截取文件:fs.ftruncate(fd, len, callback)
  • 刪除文件:fs.unlink(path, callback)
  • 建立目錄:fs.mkdir(path[, mode], callback)
  • 讀取目錄:fs.readdir(path, callback)
  • 刪除目錄:fs.rmdir(path, callback)

使用 Node 建立 Web 服務器

var http = require('http');
var fs = require('fs');
var url = require('url');
// 建立服務器
http.createServer( function (request, response) {  
// 解析請求,包括文件名
   var pathname = url.parse(request.url).pathname;   
   // 輸出請求的文件名
   console.log("Request for " + pathname + " received.");   
   // 從文件系統中讀取請求的文件內容
   fs.readFile(pathname.substr(1), function (err, data) {
      if (err) {
         console.log(err);
         // HTTP 狀態碼: 404 : NOT FOUND
         // Content Type: text/plain
         response.writeHead(404, {'Content-Type': 'text/html'});
      }else{             
         // HTTP 狀態碼: 200 : OK
         // Content Type: text/plain
         response.writeHead(200, {'Content-Type': 'text/html'});             
         // 響應文件內容
         response.write(data.toString());

index.html 文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
    <h1>個人第一個標題</h1>
    <p>個人第一個段落。</p>
</body>
</html>          
          }
          //  發送響應數據
          response.end();
       });   
    }).listen(8080);
     // 控制檯會輸出如下信息
    console.log('Server running at http://127.0.0.1:8080/');

使用 Node 建立 Web 客戶端
Node 建立 Web 客戶端須要引入 http 模塊,建立 client.js 文件,代碼以下所示:

var http = require('http'); 
// 用於請求的選項
var options = {
   host: 'localhost',
   port: '8080',
   path: '/index.html'  
}; 
// 處理響應的回調函數
var callback = function(response){
   // 不斷更新數據
   var body = '';
   response.on('data', function(data) {
      body += data;
   });   
   response.on('end', function() {
      // 數據接收完成
      console.log(body);
   });
}
// 向服務端發送請求
var req = http.request(options, callback);
req.end();

新開一個終端,執行 client.js 文件,輸出結果以下:

$ node  client.js     
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
    <h1>個人第一個標題</h1>
    <p>個人第一個段落。</p>
</body>
</html>
相關文章
相關標籤/搜索