2011-07-21 86 views
2

我試着打了一下使用的是Node.js和寫下面的代碼(它沒有任何意義,但是,這並不重要):爲什麼這個node.js代碼被阻塞?

var http = require("http"), 
    sys = require("sys"); 

sys.puts("Starting..."); 

var gRes = null; 
var cnt = 0; 

var srv = http.createServer(function(req, res){ 
    res.writeHeader(200, {"Content-Type": "text/plain"}); 
    gRes = res; 
    setTimeout(output,1000); 
    cnt = 0; 
}).listen(81); 

function output(){ 
    gRes.write("Hello World!"); 
    cnt++; 
    if(cnt < 10) 
     setTimeout(output,1000); 
    else 
     gRes.end(); 
} 

我知道有一些不好的東西,它(如使用全球gRes),但我的問題是,爲什麼這個代碼阻止第二個請求,直到第一次完成?

,如果我打開它開始寫 「Hello World」 的10倍的URL。但是如果我在第二個選項卡中同時打開它,一個選項卡將等待連接,直到另一個選項卡完成十次寫入「Hello World」。

我發現沒有任何東西可以解釋這種行爲。

+1

嘗試打開也許服務器處理在一個時間從同一個會話中的一個請求。 –

+0

hm很奇怪。如果我從兩個瀏覽器中打開它,它可以同時工作,但會覆蓋gRes到第二個頁面調用,但那是好的(我以前見過這個問題)。但是,爲什麼它不適用於一個瀏覽器的兩個選項卡? – Fender

+0

說不上來爲什麼,因爲我不太熟悉'node.js'然而,因爲它被證明是正確的,張貼作爲答案。 :) –

回答

5

肯定是你覆蓋的gRescnt變量正在使用它的第一個請求?因爲每個新的請求都會重置計數器,並且未完成的請求將永遠不會關閉],實際上,Chrome將不會一次發送兩個,正如Shadow Wizard所說的那樣,但代碼原因已嚴重破壞。

而不是使用一個全球性的,換你輸出功能作爲createServer回調中封閉。然後它將隨時訪問當地的res變量。

此代碼的工作對我來說:

var http = require("http"), 
    sys = require("sys"); 

sys.puts("Starting..."); 

var srv = http.createServer(function(req, res){ 
    res.writeHeader(200, {"Content-Type": "text/plain"}); 

    var cnt = 0; 

    var output = function() { 
     res.write("Hello World!\n"); 
     if (++cnt < 10) { 
      setTimeout(output,1000); 
     } else { 
      res.end(); 
     } 
    }; 

    output(); 

}).listen(81); 

然而要注意,直到連接已被關閉,因爲相關的頭,告訴它顯示爲它的下載是不存在的瀏覽器將不呈現任何內容。我使用telnet測試了上述內容。

+0

很好的回答:)比我的「解決方法」更容易處理所有案件 – Fender

0

我對node.js不熟悉,但通常熟悉服務器端語言 - 當瀏覽器向服務器發送請求時,服務器爲該請求創建一個會話,並從同一瀏覽器創建任何其他請求(在會話生命週期內時間)被視爲同一個會話。

可能通過設計,並有很好的理由,從同一個會話請求順序處理,一前一後 - 只有在服務器完成處理一個請求時,它會開始處理下。從兩個不同的瀏覽器

+0

嗯好的,謝謝你的回答。這很有道理 – Fender

+0

乾杯,很高興你有真正的解決方案! :) –

相關問題