I am running a server using Node.js and need to request data from another server that I am running (localhost:3001
). I need to make many requests (~200) to the
Try this:
var async = require("async");
var request = require("request");
var show_file = function (file_number,cb) {
//..Sync ops
var file_index = Math.round(Math.random() * 495) + 1;
var pinnacle_file_index = 'http://localhost:3001/generate?file='+file_index.toString();
//request instance from Request npm Module
//..Async op --> this should make async.each asynchronous
request(pinnacle_file_index, function (error, response, body) {
if(error)
return cb(error);
var object_key = "file_" + file_number.toString();
pinnacle_data[object_key] = JSON.parse(body);
return cb();
});
};
async.each(
lookup_list,
show_file,
function (err) {
if(err){
console.log("Error",err);
}else{
console.log("Its ok");
console.log(pinnacle_data);
}
});
As you have discovered, async.parallel()
can only parallelize operations that are themselves asynchronous. If the operations are synchronous, then because of the single threaded nature of node.js, the operations will run one after another, not in parallel. But, if the operations are themselves asynchronous, then async.parallel()
(or other async methods) will start them all at once and coordinate the results for you.
Here's a general idea using async.map()
. I used async.map()
because the idea there is that it takes an array as input and produces an array of results in the same order as the original, but runs all the requests in parallel which seems to line up with what you want:
var async = require("async");
var request = require("request");
// create list of URLs
var lookup_list = [];
for (var i = 0; i < 20; i++) {
var index = Math.round(Math.random() * 495) + 1;
var url = 'http://localhost:3001/generate?file=' + index;
lookup_list.push(url);
}
async.map(lookup_list, function(url, callback) {
// iterator function
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
var body = JSON.parse(body);
// do any further processing of the data here
callback(null, body);
} else {
callback(error || response.statusCode);
}
});
}, function(err, results) {
// completion function
if (!err) {
// process all results in the array here
console.log(results);
for (var i = 0; i < results.length; i++) {
// do something with results[i]
}
} else {
// handle error here
}
});
And, here's a version using Bluebird promises and somewhat similarly using Promise.map()
to iterate the initial array:
var Promise = require("bluebird");
var request = Promise.promisifyAll(require("request"), {multiArgs: true});
// create list of URLs
var lookup_list = [];
for (var i = 0; i < 20; i++) {
var index = Math.round(Math.random() * 495) + 1;
var url = 'http://localhost:3001/generate?file=' + index;
lookup_list.push(url);
}
Promise.map(lookup_list, function(url) {
return request.getAsync(url).spread(function(response, body) {
if response.statusCode !== 200) {
throw response.statusCode;
}
return JSON.parse(body);
});
}).then(function(results) {
console.log(results);
for (var i = 0; i < results.length; i++) {
// process results[i] here
}
}, function(err) {
// process error here
});
Sounds like you're just trying to download a bunch of URLs in parallel. This will do that:
var request = require('request');
var async = require('async');
var urls = ['http://microsoft.com', 'http://yahoo.com', 'http://google.com', 'http://amazon.com'];
var loaders = urls.map( function(url) {
return function(callback) {
request(url, callback);
}
});
async.parallel(loaders, function(err, results) {
if (err) throw(err); // ... handle appropriately
// results will be an array of the results, in
// the same order as 'urls', even thought the operation
// was done in parallel
console.log(results.length); // == urls.length
});
or even simpler, using async.map
:
var request = require('request');
var async = require('async');
var urls = ['http://microsoft.com', 'http://yahoo.com', 'http://google.com', 'http://amazon.com'];
async.map(urls, request, function(err, results) {
if (err) throw(err); // handle error
console.log(results.length); // == urls.length
});