Node.JS - 如何识别哪个异步 HTTP GET 响应在回调中返回数据?
Node.JS - How to identify which async HTTP GET response is returning data in a callback?
我正在尝试遵循有关异步原则的 NodeSchool 教程。有一节课要求:
- 向 3 个 URL 发出异步 GET 请求
- 使用回调收集 HTTP 响应中返回的数据
- 打印从每个响应中收集的数据,保留相关输入 URL 的顺序
我想到的一种方法是进行 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 的响应?
注意: 作业明确禁止使用第三方库,例如 async 或 after.
编辑: 我尝试过的另一件事(显然也失败了)是像这样内联 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;
}
}
编辑了我的原始答案。
我正在尝试遵循有关异步原则的 NodeSchool 教程。有一节课要求:
- 向 3 个 URL 发出异步 GET 请求
- 使用回调收集 HTTP 响应中返回的数据
- 打印从每个响应中收集的数据,保留相关输入 URL 的顺序
我想到的一种方法是进行 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 的响应?
注意: 作业明确禁止使用第三方库,例如 async 或 after.
编辑: 我尝试过的另一件事(显然也失败了)是像这样内联 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;
}
}
编辑了我的原始答案。