Node.js - 为什么我的一些回调没有异步执行?

时间:2014-03-04 04:06:56

标签: javascript node.js http asynchronous callback

Noob使用回调作为Node和http类的控制流模式的问题。基于我对事件循环的理解,所有代码都是阻塞的,i / o是非阻塞的并且使用回调,这里是一个简单的http服务器和一个伪休息函数:

// 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”服务器,则“慢”正在处理并以串行/同步方式响应,以便3个响应以30秒的间隔出现。如果它们被异步处理,我期待彼此之后的响应。

我做错了什么?

感谢您的想法。

1 个答案:

答案 0 :(得分:3)

这实际上不是服务器的错。您的浏览器正在打开一个连接并在请求之间重新使用它,但是一个请求在前一个请求完成之前无法开始。您可以通过以下几种方式看到这一点:

  • 查看Chrome开发工具的网络标签 - 最长的条目将在blocking状态显示请求,直到前两个完成。
  • 尝试在不同浏览器中打开慢速页面(或者在普通和隐身窗口中打开一个) - 这样可以防止共享连接。

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