【问题标题】:Why is this node.js code blocking?为什么这个 node.js 代码会阻塞?
【发布时间】:2011-07-21 08:02:08
【问题描述】:

我试着玩了一下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 次。但是,如果我在第二个选项卡中同时打开它,一个选项卡会等待连接,直到另一个选项卡完成十次“Hello World”写入。

我没有发现任何可以解释这种行为的东西。

【问题讨论】:

  • 尝试从两个不同的浏览器打开,也许服务器一次处理来自同一个会话的请求。
  • 嗯,很奇怪。如果我从两个浏览器打开它,它会同时工作,但会将 gRes 覆盖到第二个页面调用,但没关系(我以前见过这个问题)。但为什么它不适用于一个浏览器的两个标签页?
  • 不知道为什么,因为我不熟悉node.js,但事实证明它是正确的,将其发布为答案。 :)

标签: javascript node.js


【解决方案1】:

肯定是您覆盖了第一个请求正在使用的 gRescnt 变量吗?

[EDIT 实际上,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 测试了上述内容。

【讨论】:

  • 很好的答案 :) 比我没有处理所有情况的“解决方法”要容易得多
【解决方案2】:

我不熟悉node.js,但通常熟悉服务器端语言 - 当浏览器向服务器发送请求时,服务器会为该请求和来自同一浏览器的任何其他请求创建一个会话(在会话内life time) 被视为同一个 Session。

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

【讨论】:

  • 干杯,很高兴你得到真正的解决方案! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 2017-07-14
  • 2020-10-30
  • 2015-11-03
  • 1970-01-01
  • 2011-10-16
相关资源
最近更新 更多