node.js:与回调顺序混淆

时间:2014-06-27 05:07:35

标签: node.js asynchronous callback nonblocking

我刚开始使用node.js.我发现它使用的异步编码风格确实非常令人印象深刻。但是,对于我们这些习惯于Java和Python的人来说,它需要一些时间来适应它。

我知道以下代码运行正常。这个论坛上的几个问题都证实了这一点。我也是自己尝试过的。

var http = require('http'),
fs = require('fs');
fs.readFile('./index.html', function (err, html) {
    if (err) {
        //throw err; 
    }       
    http.createServer(function(request, response) { 
        console.log("Server started");
        response.writeHeader(200, {"Content-Type": "text/html"});  
        response.write(html); 
        response.write("Other things");
        response.end();  
    }).listen(3000);
});

我解释的方式如下:

1. Try reading the html file
   i. When done create a server 
   ii. Send it over to the client
2. Do everything else.

但是,我们也可以有如下思路:

1. Create the server
2. Try reading the file
   i. When done. Send it over to the client
3. In the meanwhile do anything else the server might be asked to do. 

与第二个思路相对应的代码是:

var http = require('http'),
fs = require('fs');

http.createServer(function(request, response) { 
        console.log("Server started");
        response.writeHeader(200, {"Content-Type": "text/html"});
        fs.readFile('./index.html', function (err, html) {
            if (err) {
            //throw err; 
            }
            response.write(html);
            response.write("Other things");
        });
        response.end();  
}).listen(3000); 

虽然第一个代码按预期工作。第二个在浏览器中根本不显示任何内容。

为什么第二连串思想错了?

1 个答案:

答案 0 :(得分:0)

实际上,这里发生的是每次有传入请求时都会调用以下函数:

function(request, response) { 
    console.log("Server started");
    response.writeHeader(200, {"Content-Type": "text/html"});  
    response.write(html); 
    response.write("Other things");
    response.end();  
}

您将其替换为:

function(request, response) { 
    console.log("Server started");
    response.writeHeader(200, {"Content-Type": "text/html"});
    fs.readFile('./index.html', function (err, html) {
        if (err) {
        //throw err; 
        }
        response.write(html);
        response.write("Other things");
    });
    response.end();  
}

现在,它将执行以下操作:

  1. 写标题
  2. 将readFile排队
  3. 立即执行以下操作:response.end();
  4. 当读完文件并想要写内容时,您已经结束了回复