1. 程式人生 > >Node.js:創建應用+回調函數(阻塞/非阻塞)

Node.js:創建應用+回調函數(阻塞/非阻塞)

我們 異步化 沒有 就會 幾分鐘 能說 image console cti

一、創建應用

  如果我們使用PHP來編寫後端的代碼時,需要Apache 或者 Nginx 的HTTP 服務器,並配上 mod_php5 模塊和php-cgi。從這個角度看,整個"接收 HTTP 請求並提供 Web 頁面"的需求根本不需要 PHP 來處理。

  不過對 Node.js 來說,概念完全不一樣了。使用 Node.js 時,我們不僅僅在實現一個應用,同時還實現了整個 HTTP 服務器。事實上,我們的 Web 應用以及對應的 Web 服務器基本上是一樣的。

  在我們創建 Node.js 第一個 "Hello, World!" 應用前,讓我們先了解下 Node.js 應用是由哪幾部分組成的:

  1. 引入 required 模塊:我們可以使用 require 指令來載入 Node.js 模塊。

  2. 創建服務器:服務器可以監聽客戶端的請求,類似於 Apache 、Nginx 等 HTTP 服務器。

  3. 接收請求與響應請求 服務器很容易創建,客戶端可以使用瀏覽器或終端發送 HTTP 請求,服務器接收請求後返回響應數據

1、引入 required 模塊

  我們使用 require 指令來載入 http 模塊,並將實例化的 HTTP 賦值給變量 http,實例如下:

2、創建服務器

  接下來我們使用 http.createServer() 方法創建服務器,並使用 listen 方法綁定 8888 端口。 函數通過 request, response 參數來接收和響應數據。

  實例如下,在你項目的根目錄下創建一個叫 server.js 的文件,並寫入以下代碼:

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/);

  以上代碼我們完成了一個可以工作的 HTTP 服務器。使用 node 命令執行以上的代碼,打開瀏覽器訪問 http://127.0.0.1:8888/,你會看到一個寫著 "Hello World"的網頁。

技術分享圖片

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

二、回調函數

  Node.js 異步編程的直接體現就是回調。異步編程依托於回調來實現,但不能說使用了回調後程序就異步化了。回調函數在完成任務後就會被調用,Node 使用了大量的回調函數,Node 所有 API 都支持回調函數。例如,我們可以一邊讀取文件,一邊執行其他命令,在文件讀取完成後,我們將文件內容作為回調函數的參數返回。這樣在執行代碼時就沒有阻塞或等待文件 I/O 操作。這就大大提高了 Node.js 的性能,可以處理大量的並發請求。

1、阻塞代碼實例

var fs = require("fs");
var data = fs.readFileSync(input.txt);

console.log(data.toString());
console.log("程序執行結束!");
//結果:先打印input裏面內容,再打印程序結束

2、非阻塞代碼實例

var fs = require("fs");
fs.readFile(input.txt, function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});

console.log("程序執行結束!");
//結果:先打印程序結束,再打印input裏面內容

  以上兩個實例我們了解了阻塞與非阻塞調用的不同。第一個實例在文件讀取完後才執行完程序。 第二個實例我們不需要等待文件讀取完,這樣就可以在讀取文件時同時執行接下來的代碼,大大提高了程序的性能。

  因此,阻塞是按順序執行的,而非阻塞是不需要按順序的,所以如果需要處理回調函數的參數,我們就需要寫在回調函數內。

3、阻塞和非阻塞,同步異步的理解

  阻塞和非阻塞,同步和異步是node.js裏經常遇到的詞匯,我舉個簡單的例子來說明:

  我要看足球比賽,但是媽媽叫我燒水,電視機在客廳,燒水要在廚房。家裏有2個水壺,一個是普通的水壺,另一個是水開了會叫的那種水壺。我可以:

  (1)用普通的水壺燒,人在邊上看著,水開了再去看球。(同步,阻塞)這個是常規做法,但是我看球不爽了。

  (2)用普通水壺燒,人去看球,隔幾分鐘去廚房看看。(同步,非阻塞)這個又大問題,萬一在我離開的幾分鐘水開了,我就麻煩了。

  (3)用會叫的水壺,人在邊上看著。(異步,阻塞)這個沒有問題,但是我太傻了。

  (4)用會叫的水壺,人去看球,聽見水壺叫了再去看。(異步,非阻塞)這個應該是最好的。

  等著看球的我:阻塞,看著電視的我:非阻塞

  普通水壺:同步,會叫的水壺:異步

  所以,異步往往配合非阻塞,才能發揮出威力。

Node.js:創建應用+回調函數(阻塞/非阻塞)