我想对数组中的每个元素进行http调用,并将所有响应组合到一个数组中,如下所示:
result = [] ; i = 0
for item in array
options = get_options(item)
request options, (err, res, body)->
result[i++] = body
// when all calls are done, console.log the 'result' array
我正在查看异步模块,但我不确定如何使用它。
答案 0 :(得分:2)
试试这个,应该有效。您可能希望尝试使用mapLimit来限制并行请求或mapSeries按顺序执行此操作。
var async = require('async');
var request = require('request');
async.map(['url1', 'url2'], function(item, callback){
request(item, function (error, response, body) {
callback(error, body);
});
}, function(err, results){
console.log(results);
});
对于您的示例,我需要查看您的get_options函数。它同步吗?如果是,你可以这样做
var async = require('async');
var request = require('request');
var options;
async.map([item1, item2], function(item, callback){
options = get_options(item);
request(options, function (error, response, body) {
callback(error, body);
});
}, function(err, results){
console.log(results);
});
如果你的get_options是异步的并接受回调,请执行以下操作:
var async = require('async');
var request = require('request');
async.map([item1, item2], function(item, callback){
get_options(item, function(err, option){
if(err) {
callback(err);
}
else{
request(options, function (error, response, body) {
callback(error, body);
});
}
});
}, function(err, results){
console.log(results);
});
答案 1 :(得分:1)
使用异步库的地图功能
var makeRequest = function(item, callback){
var options = get_options(item);
// handle http errors and getting access to body properly
http.get(options,res){
callback(null, res)
}
}
async.map(['item1','item2','item3'], makeRequest(item, callback), function(err, results){
//check errors do stuff with results
});
答案 2 :(得分:0)
如果您对使用承诺感兴趣,也可以使用答案:
var Q = require('q');
var http = require('http');
var httpGet = function(url) {
var data = "", defer = Q.defer();
http.get(url, function (res) {
var content_length = parseInt(res.headers['content-length'], 10);
var total_downloaded = 0;
if (res.statusCode !== 200) {
defer.reject("HTTP Error " + res.statusCode + " for " + url);
return;
}
res.on("error", defer.reject);
res.on("data", function (chunk) {
data += chunk;
total_downloaded += chunk.length;
var percentage = Math.floor((total_downloaded / content_length) * 100);
defer.notify(percentage);
});
res.on("end", function () { defer.resolve(data); });
});
return defer.promise;
}
这使用Q promises库。你可以这样使用它:
var promise = httpGet("http://example.com/");
promise.then(function (data) {
// Do something with data.
}, function (reason) {
// Do something with the error
}, function (progress) {
// Do something with the progress update (% so far)
});