Node.js – 为什么我的一些callback不是asynchronous执行的?

Noob关于使用callback作为控制stream模式与Node和http类的问题。 根据我对事件循环的理解,所有的代码都是阻塞的,I / O是非阻塞的,使用callback函数,下面是一个简单的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”,然后在另一个选项卡中input“/ test / foo”,我会得到以下行为 – “foo”立即响应“Bar”,然后迟到30秒,“慢”以“时间30秒”作为响应。 这是我期待的。

但是,如果我在浏览器中打开3个选项卡,并在每个选项卡中连续点击“/ test / slow”,则“slow”正在被处理并连续/同步响应,以便以30秒的间隔出现3个响应。 如果他们被asynchronous处理,我期待着对方的回应。

我究竟做错了什么?

谢谢你的想法。

这其实不是服务器的错。 您的浏览器正在打开一个连接并在请求之间重新使用它,但是一个请求只有在前一个请求完成时才能开始。 你可以看到几个方面:

  • 查看Chrome开发工具的networking选项卡 – 最长的条目将显示处于blocking状态的请求,直到前两个完成。
  • 尝试在不同的浏览器中打开慢页面(或者在普通窗口和隐身窗口中打开一个页面) – 这会阻止共享连接。

因此,只有当相同的浏览器窗口向同一服务器发出多个请求时才会发生这种情况。 另请注意,XHR(AJAX)请求将打开单独的连接,以便它们可以并行执行。 在现实世界中,这不会是一个问题。