深入理解Node.js基於事件驅動的回調

來源:互聯網
上載者:User

標籤:注意   server   進程   命令列   基於   請求   response   strong   服務   

回調和非同步呼叫的關係

首先明確一點,回調並非是非同步呼叫,回調是一種解決非同步函數執行結果的處理方法。在非同步呼叫,如果我們希望將執行的結果返回並且處理時,可以通過回調的方法解決。為了能夠更好的區分回調和非同步回調的區別,我們來看一個簡單的例子,代碼如下:

function waitFive(name, function_name){    var pus = 0;    var currentDate = new Date();    while(pus < 5000){        var now = new Date();        pus = now - currentDate;    }    function_name(name);}function echo(name){    console.log(name);}waitFive("bob", echo);console.log(‘its over‘);

以上代碼是一個回調邏輯,但不是一個非同步代碼邏輯,因為其中並沒有涉及 Node.js 的非同步呼叫介面。waitFive()函數執行時,整個代碼執行過程都會等待 waitFive() 函數的執行,而並非如非同步呼叫那樣waitFive未結束,還會繼續執行console.log(‘its over’); 

因此,回調還是一種阻塞式調用。

非同步函數往往不是直接返回執行結果,而是通過事件驅動方式,將執行結果返回到回呼函數中,之後在回呼函數中處理相應的邏輯代碼。

Node.js中很多API的調用模式是非同步呼叫的,因此在學習Node.js過程中理解非同步呼叫、同步調用和回調是非常重要的。

為什麼非同步函數需要回呼函數?

先看這樣一個例子:

var dns = require(‘dns‘);  // require dns 模組var address = dns.resolved4(‘www.baidu.com‘, function(address){});//dns 同步解析console.log(address);

當我們擷取address值時,會出現異常,提示address沒有定義undefined。列印出address,可以看到第二個例子結果為null,原因很簡單,非同步函數dns.resolve4()還未執行結束時,就已經執行到 console.log(address),因此最終 address 為 null。既然非同步函數出現這個問題,我們就可以使用回調去擷取函數。如下代碼,通過回呼函數擷取執行的結果 address 值:

var dns = require(‘dns‘);dns.resolve4(‘www.baidu.com‘, function(address){    console.log(address);})
Node.js —— 基於事件驅動的回調

為什麼它對我們用 Node.js 寫網路應用是具有意義的?

當我們使用 http.createServer 方法的時候,我們當然不只是想要一個偵聽某個連接埠的伺服器,我們還想要它在伺服器收到一個HTTP請求的時候做點什麼。問題是,這是非同步:請求任何時候都可能到達,但是我們的伺服器卻跑在一個單進程中。

寫PHP應用的時候,我們一點也不為此擔心:任何時候當有請求進入的時候,網頁伺服器(通常是Apache)就為這一請求建立一個進程,並且開始從頭到尾執行相應的PHP指令碼。

我們先來看一個基於Node.js簡約而不簡單的HTTP伺服器:

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程式中,當一個新的請求到達8888連接埠的時候,我們怎麼控制流程程呢?

嗯,這就是Node.js/JavaScript的事件驅動設計能夠真正幫上忙的地方了 —— 雖然我們還得學一些新概念才能掌握它。讓我們來看看這些概念是怎麼應用在我們的伺服器代碼裡的。

我們建立了伺服器,並且向建立它的方法傳遞了一個函數。無論何時我們的伺服器收到一個請求,這個函數就會被調用。我們不知道這件事情什麼時候會發生,但是我們現在有了一個處理請求的地方:它就是我們傳遞過去的那個函數。至於它是被預先定義的函數還是匿名函數,都無關緊要了。這個就是傳說中的 回調(Node.js中的非同步回調)。

讓我們再來琢磨琢磨 [ Node.js中的非同步回調 ] 這個概念。

我們怎麼證明在建立完伺服器之後,即時沒有HTTP請求進來,我們的回呼函數也沒有被調用的情況下,我們的代碼還繼續有效呢?試試這個:

var http = require("http");http.createServer(function(request, response){    console.log("Request received.");    response.writeHead(200, {"Content-Type": "text/plain"});    response.write("Hello World");    response.end();}).listen(8888);console.log("Server has started.");

注意:在匿名回呼函數觸發的地方,我們用 console.log 輸出了一段文本;在HTTP伺服器開始工作之後,也輸出一段文本。

當我們與往常一樣,運行 node server.js 時,它會馬上在命令列上輸出 “Server has started.”。當我們向伺服器發出請求(在瀏覽器訪問http://localhost:8888),“Request received.”這條訊息就會在命令列中出現。(請注意,當我們在伺服器訪問網頁時,我們的伺服器可能會輸出兩次“Request received.”。那是因為大部分瀏覽器都會在你訪問 http://localhost:8888 時嘗試讀取 http://localhost:8888/favicon.ico) —— 這就是事件驅動的非同步伺服器端 JavaScript 和它的回調啦! 

深入理解Node.js基於事件驅動的回調

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.