我尝试玩一下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),但我的问题是,为什么这段代码会阻止第二个请求,直到第一个请求完成为止?
如果我打开 URL,它会开始写入“Hello World”10 次。但是,如果我在第二个选项卡中同时打开它,一个选项卡将等待连接,直到另一个选项卡完成十次“Hello World”的写入。
我没有发现任何可以解释这种行为的东西。
最佳答案
这肯定是您覆盖了第一个请求所使用的 gRes
和 cnt
变量吗?
[编辑实际上,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);
但请注意,在连接关闭之前浏览器不会呈现任何内容,因为告诉它在下载时显示的相关 header 不存在。我使用 telnet
测试了上述内容。
关于javascript - 为什么这个 Node.js 代码会阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6772981/