Reputation: 7451
I'm building a small application that needs to make multiple HTTP calls to an external API and amalgamate the results into a single object or array. e.g.
Connect to endpoint and get auth key - pass auth key to step
Get summary of available items List items - Connect to endpoint using auth key and get JSON results - create an object containing summary results and pass to step 3.
Iterate over passed object summary results and call API for each item in the object to get detailed information for each summary line - Then create a single JSON data structure that contains the summary and detail information.
Using the nodejs async library I can get as far as step 2, however because step 3 involves multiple HTTP requests each with their own callbacks, I'm getting lost in callback hell.
Is there a recommended way to easily deal with this type of use case using node?
Upvotes: 0
Views: 176
Reputation: 1506
A simple solution would be counting you callbacks:
var results = [];
function final_callback(results)
function callback(result){
results.push(result):
if (results.length == number of requests){
final_callback(results);
}
}
A more decent solution would be using and event EventEmitter with a counter:
my_eventEmitter.on('init_counter',function(counter){
my_eventEmitter.counter=counter;
});
my_eventEmitter.on('result',function(result){
if( my_eventEmitter.counter == 0 ) return;
//stop all callbacks after counter is 0;
my_eventEmitter.results.push(result);
my_eventEmitter.counter--;
if( my_eventEmitter.counter == 0 ){
my_eventEmitter.emit('final_callback');
}
});
my_eventEmitter.on('final_callback', function(){
//handle my_eventEmitter.results here
})
.... now you just have to do your for but before it send init_counter to the event emitter
my_eventEmitter.emit('init_counter',50);
for(i=0; i<50; i++) async_function_call(some_params, function(result){
my_eventEmitter.emit('result',result);
});
Upvotes: 0
Reputation: 56587
Dealing with multiple callbacks is not easy. However there already are libraries which can help you, like Caolan's async.js. The solution may look like that:
var async = require("async");
var myRequests = [];
myArray.forEach(function(item) {
myRequests.push(function(callback) {
setTimeout(function() {
// this only emulates the actual call
callback(result);
}, 500);
});
});
async.parallel(myRequests, function(results) {
// this will fire when all requests finish whatever they are doing
});
Upvotes: 1