I have a function foo which makes multiple (parallel) asynchronous calls in a loop. I need to somehow wait until the results of all of the calls are available.
Use promises. Precisely, Promise.all was designed for this.
It takes an array (or iterable) of promises, and returns a new promise which is resolved when all the promises of the array have been resolved. Otherwise, it rejects when any promise of the array rejects.
function someAsyncFunction(data, resolve, reject) {
setTimeout(function() {
if(Math.random() < .05) {
// Suppose something failed
reject('Error while processing ' + data.someParam);
} else {
// Suppose the current async work completed succesfully
resolve(data.someParam);
}
}, Math.random() * 1000);
}
function foo() {
// Create an array of promises
var promises = [];
for (var i = 0; i < 10; i++) {
// Fill the array with promises which initiate some async work
promises.push(new Promise(function(resolve, reject) {
someAsyncFunction({someParam:i}, resolve, reject);
}));
}
// Return a Promise.all promise of the array
return Promise.all(promises);
}
var result = foo().then(function(results) {
console.log('All async calls completed successfully:');
console.log(' --> ', JSON.stringify(results));
}, function(reason) {
console.log('Some async call failed:');
console.log(' --> ', reason);
});
Note that the results will be given according to the order of the array of promises, not in the order that the promises were resolved in.