为什么这个node.js代码阻塞?

时间:2011-07-21 08:02:08

标签: javascript 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();
}

我知道其中有一些不好的东西(比如全局使用gR),但我的问题是,为什么这段代码在第一次完成之前阻止了第二个请求?

如果我打开网址,它会开始写“Hello World”10次。但是如果我在第二个标签中同时打开它,一个标签会等待连接,直到另一个标签完成“Hello World”十次完成。

我发现没有什么可以解释这种行为。

2 个答案:

答案 0 :(得分: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测试了上述内容。

答案 1 :(得分:0)

我不熟悉node.js但一般熟悉服务器端语言 - 当浏览器向服务器发送请求时,服务器会为该请求创建一个会话以及来自同一浏览器的任何其他请求(在会话生命周期)被视为同一个会话。

可能是出于设计,并且有充分的理由,来自同一会话的请求是一个接一个地顺序处理的 - 只有在服务器完成处理一个请求之后,它才会开始处理下一个请求。