2012-12-20 46 views
5

我是新來的node.js,我嘗試使用setTimeout來模擬長連接並希望它異步執行。如何在node.js中異步使用setTimeout

var http = require('http'); 

http.createServer(function (request, response) { 
    console.log('New request @ ' + request.url); 
    (function (response) { 
     setTimeout(function() { 
      console.log('Time is up'); 
      response.writeHead(200, {"Content-Type": "text/plain"}); 
      response.end('Hello World\n'); 
     }, 3000); 
    })(response); 
}).listen(8124); 

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

但是,上面的代碼表現得像一個同步單線程應用程序,它每3秒只能處理一個請求。

我認爲node.js中的所有內容都應該異步執行。那麼,這裏有什麼問題?

回答

8

SetTimeout是異步的,你不需要中間的匿名函數,只需寫這個。

var http = require('http'); 

http.createServer(function (request, response) { 
    console.log('New request @ ' + request.url); 
    setTimeout(function() { 
    console.log('Time is up'); 
    response.writeHead(200, {"Content-Type": "text/plain"}); 
    response.end('Hello World\n'); 
    }, 3000); 
}).listen(8124); 

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

如果您生成10個併發請求,則總計時間約爲3秒,這意味着它是異步的。您可以使用ab工具來檢查,或者如果您編程節點,可能更容易安裝http-perf。並運行nperf -c 10 -n 10 http://127.0.0.1:8124

+0

我測試過ab,你說的對,setTimeout是一個異步函數。但是,如果我同時在Chrome中打開多個標籤,它會在5秒鐘間隔內逐一結束,這有點奇怪。 – Jack

+0

我認爲你只是沒有足夠的快速點擊Chrome中的標籤.. :) – balazs

+2

Chrome不會同時請求相同的URL。如果您爲該網址添加了一個變體,例如第一個選項卡請求http://127.0.0.1:8124/0,第二個請求請求http://127.0.0.1:8124/1等,那麼他們應該像你期望的那樣行事。請參閱http://stackoverflow.com/questions/15852011/why-settimeout-blocks-eventloop – Jason

-3

var async,
__slice = [] .slice;

async = require(「async」);

async.setTimeOut =函數(){
       變種精氨酸,指定參數時,回調,延遲,runWithTimeOut; callback = arguments [0],delay = arguments [1],arg = arguments [2],args = 4 < = arguments.length?
          __slice.call(arguments,3):[];
        runWithTimeOut =函數(){
               返回的setTimeout(回調,延遲,精氨酸,參數);
       };

       返回async.parallel([runWithTimeOut]);
};