Node.JS - 如何识别哪个异步 HTTP GET 响应在回调中返回数据?

Node.JS - How to identify which async HTTP GET response is returning data in a callback?

我正在尝试遵循有关异步原则的 NodeSchool 教程。有一节课要求:

我想到的一种方法是进行 3 个单独的回调,每个回调写入其自己的专用缓冲区。但这对我来说似乎是一个糟糕的解决方案,因为它需要重复代码并且不可扩展。但是,由于缺少更好的术语,我一直在寻找另一种方法来获得回调以记住 "where it came from"。或者调用的顺序等等

我觉得我很接近,但我已经在 'close' 停留了足够长的时间来寻求帮助。这是我迄今为止最接近的感觉:

var http = require('http');

var replies = 0;
var results = ['','',''];
var running = '';

for(var i = 2; i < 5; i++) {
    http.get(process.argv[i], function (response) {
        response.setEncoding('utf8');
        response.on('data', handleGet);
        response.on('error', handleError);
        response.on('end', handleEnd);
    });
}

function handleGet(data) {
    running += data;
}

function handleError(error) {
    console.log(error);
}

function handleEnd() {
    results[replies] = running;
    running = '';
    replies++;
    if(replies === 3) {
        for(var i = 0; i < 3; i++) {
            console.log(totals[i]);
        }
    }
}

如何让回调识别其响应是对哪个 GET 的响应?

注意: 作业明确禁止使用第三方库,例如 asyncafter.

编辑: 我尝试过的另一件事(显然也失败了)是像这样内联 handleGet 的回调定义,以尝试保留 'index'回调:

response.on('data', function(data) {
    results[i-2] += data;
});

在执行时,这总是索引到结果[3],因为异步回调只有在 for 循环已经完成很久之后才会发生。 (实际上,我不确定为什么 i 的值完全保留为 5,因为据我所知,完成的 for 循环会超出范围……回想起来我会认为它是未定义的。)

您可以使用 'this' 对象:

var http = require('http');

http.get('http://www.google.com', function (response) {
    response.setEncoding('utf8');
    response.on('data', function(chunk) {
        console.log(this); // Holds the respons object
        console.log(this.headers.location); // Holds the request url
    });
});

我建议使用您的第二个解决方案,但传递 i 的值并创建另一个包含该变量的函数。我的意思是:

(function(){
  var index = i;
  http.get(process.argv[i], function (response) {
        response.setEncoding('utf8');
        response.on('data', handleGetFrom(index));
        response.on('error', handleError);
        response.on('end', handleEnd);
    })
}());

handleGetFrom:

var handleGetFrom = function(i) {
    return function(data) {
     results[i-2] += data;
    }
}

编辑了我的原始答案。