我知道Node是非阻塞的,但我刚刚意识到http.listen(8000)
的默认行为意味着所有的HTTP请求都是一次处理一个。我知道我不应该对此感到惊讶(这就是端口的工作方式),但它确实让我很想知道如何编写代码,以便能够处理多个并行的HTTP请求。
那么,编写服务器的最好方法是什么,这样它就不会占用端口80,并且长时间运行的响应不会导致长请求队列?
为了说明这个问题,请尝试运行下面的代码,并同时在两个浏览器选项卡中加载它。
var http = require('http');
http.createServer(function (req, res) {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.write("<p>" + new Date().toString() + ": starting response");
setTimeout(function () {
res.write("<p>" + new Date().toString() + ": completing response and closing connection</p>");
res.end();
}, 4000);
}).listen(8080);
发布于 2014-03-09 00:47:41
您的代码可以接受多个连接,因为作业是在setTimeout调用的回调函数中完成的。
但是如果你代替setTimeout做一件繁重的工作..。那么,node.js将不会接受其他多个连接是真的!SetTimeout意外地释放了进程,因此node.js可以接受其他作业,您的代码将在其他“线程”中执行。
我不知道哪种方式才是正确的实现方式。但这似乎就是它的工作方式。
发布于 2017-07-02 03:30:35
浏览器会阻止其他相同的请求。如果你从不同的浏览器调用它,那么它将并行工作。
发布于 2017-05-22 20:24:42
我使用了以下代码来测试请求处理
app.get('/', function(req, res) {
console.log('time', MOMENT());
setTimeout( function() {
console.log(data, ' ', MOMENT());
res.send(data);
data = 'changing';
}, 50000);
var data = 'change first';
console.log(data);
});
因为这个请求不需要那么多的处理时间,除了50秒的setTimeout和所有的超时都像往常一样一起处理。
一起响应3个请求-
time moment("2017-05-22T16:47:28.893")
change first
time moment("2017-05-22T16:47:30.981")
change first
time moment("2017-05-22T16:47:33.463")
change first
change first moment("2017-05-22T16:48:18.923")
change first moment("2017-05-22T16:48:20.988")
change first moment("2017-05-22T16:48:23.466")
在此之后,我进入了第二阶段...也就是说,如果我的请求花了这么多时间来处理同步文件或其他需要时间的事情,那该怎么办?
app.get('/second', function(req, res) {
console.log(data);
if(req.headers.data === '9') {
res.status(200);
res.send('response from api');
} else {
console.log(MOMENT());
for(i = 0; i<9999999999; i++){}
console.log('Second MOMENT', MOMENT());
res.status(400);
res.send('wrong data');
}
var data = 'second test';
});
由于我的第一个请求仍在处理中,因此Node没有接受我的第二个请求。因此,我得到了以下2个请求的响应-
undefined
moment("2017-05-22T17:43:59.159")
Second MOMENT moment("2017-05-22T17:44:40.609")
undefined
moment("2017-05-22T17:44:40.614")
Second MOMENT moment("2017-05-22T17:45:24.643")
因此,对于所有异步功能,Node中都有一个虚拟线程,Node在完成之前的请求异步工作(如fs、mysql或调用API)之前接受其他请求,但它将自己保留为单线程,并在完成之前的所有请求之前不处理其他请求。
https://stackoverflow.com/questions/17129672
复制相似问题