Node.js - 为啥我的一些回调没有异步执行?
Posted
技术标签:
【中文标题】Node.js - 为啥我的一些回调没有异步执行?【英文标题】:Node.js - Why are some of my callbacks not executing asynchronously?Node.js - 为什么我的一些回调没有异步执行? 【发布时间】:2014-04-05 10:35:42 【问题描述】:关于使用回调作为 Node 和 http 类的控制流模式的新手问题。根据我对事件循环的理解,所有代码都是阻塞的,i/o 是非阻塞的并使用回调,这是一个简单的 http 服务器和一个伪 rest 函数:
// Require
var http = require("http");
// Class
function REST() ;
// Methods
REST.prototype.resolve = function(request,response,callback)
// Pseudo rest function
function callREST(request, callback)
if (request.url == '/test/slow')
setTimeout(function()callback('time is 30 seconds'),30000);
else if (request.url == '/test/foo')
callback('bar');
// Call pseudo rest
callREST(request, callback);
// Class
function HTTPServer() ;
// Methods
HTTPServer.prototype.start = function()
http.createServer(function (request, response)
// Listeners
request.resume();
request.on("end", function ()
// Execute only in not a favicon request
var faviconCheck = request.url.indexOf("favicon");
if (faviconCheck < 0)
//Print
console.log('incoming validated HTTP request: ' + request.url);
//Instantiate and execute on new REST object
var rest = new REST();
rest.resolve(request,response,function(responseMsg)
var contentType = 'Content-Type': 'text/plain';
response.writeHead(200, contentType); // Write response header
response.end(responseMsg); // Send response and end
console.log(request.url + ' response sent and ended');
);
else
response.end();
);
).listen(8080);
// Print to console
console.log('HTTPServer running on 8080. PID is ' + process.pid);
// Process
// Create http server instance
var httpServer = new HTTPServer();
// Start
httpServer.start();
如果我打开浏览器并在一个选项卡中使用“/test/slow”然后在另一个选项卡中使用“/test/foo”访问服务器,我会得到以下行为 - “foo”立即以“Bar”响应,然后迟到 30 秒,“慢”响应“时间为 30 秒”。这是我所期待的。
但是,如果我在浏览器中打开 3 个选项卡并在每个选项卡中连续使用“/test/slow”访问服务器,则“slow”正在被处理并串行/同步响应,因此 3 个响应以 30 秒的间隔出现.如果它们是异步处理的,我希望它们会一个接一个地得到响应。
我做错了什么?
感谢您的意见。
【问题讨论】:
我认为您的浏览器被阻止了。尝试 3 种不同的浏览器。 @cookiemonster 但是,为什么浏览器会阻止请求? @thefourtheye:因为它们指向同一个 url。我现在正在做一些测试,但我似乎想起了一些类似的问题。 @cookiemonster 哦,是这样吗?即使我很惊讶看到这种行为。请分享你的发现:) @thefourtheye:已确认。如果我将callREST
中的if
语句更改为:if (request.url.slice(0,-2) == '/test/slow')
,并向/test/slow/1
、/test/slow/2
和/test/slow/3
发送请求,它会按预期工作。
【参考方案1】:
这其实不是服务器的错。您的浏览器正在打开一个连接并在请求之间重新使用它,但一个请求在前一个完成之前无法开始。您可以通过以下几种方式看到这一点:
查看 Chrome 开发工具的网络选项卡 - 最长的条目将显示处于blocking
状态的请求,直到前两个完成。
尝试在不同的浏览器中打开慢速页面(或在普通和隐身窗口中各一个) - 这会阻止共享连接。
因此,只有当同一个浏览器窗口向同一个服务器发出多个请求时,才会发生这种情况。另外,请注意 XHR (AJAX) 请求将打开单独的连接,以便它们可以并行执行。在现实世界中,这不是问题。
【讨论】:
选择这个作为最完整的答案。经过测试和验证。以上是关于Node.js - 为啥我的一些回调没有异步执行?的主要内容,如果未能解决你的问题,请参考以下文章