Reputation: 3053
How can one create a for
loop that waits for an asynchronous call to complete prior to starting a new iteration of a loop WITHOUT a library (like jQuery)?
Example:
var items = [1,2,3,4,5];
for (var i = 0; i < items.length; i++) {
var promise = new Promise(function(resolve, reject){
asyncAPIcall({
body : item[i]
}, function(error, response){
if(error) {
reject();
} else {
resolve();
}
});
promise.then(function() {
//continue loop
}, function() {
//break loop
});
}
Thanks
UPDATE (4/29)
I thought of this solution, where I create a function that calls itself:
var items = [1,2,3,4,5];
var counter = items.length - 1; //minus one since array is zero based.
function myLoop(){
asyncAPIcall({
body : item[counter]
}, function(error, response){
if(error) {
// Error message.
} else {
counter = counter - 1;
if(counter == -1){
//Done
}
else {
myLoop();
}
}
});
}
Upvotes: 1
Views: 308
Reputation: 5538
You can use reduce to make them process sequentially (or set up the promise chain using a regular for loop -- I prefer reduce, myself).
let promise = items.reduce((carry, current) => {
return carry.then(arr => {
return asyncAPIcall({ body: current }).then(result => arr.concat([ result ]));
});
}, Promise.resolve([]));
promise.then(finalResult => {
console.log('final result:', finalResult);
});
This may be more than you need, if you don't actually need to capture the results of those promise resolutions, though. Also note that you'll still have a promise at the end of it, which will contain an array of the results of each promise, corresponding to their original array position.
Also, here is a mocked version of the asyncAPIcall
, which should assist with showing the order of operations here, if you want to trace through how / where the methods are called.
function asyncAPIcall(obj) {
console.log('asyncAPIcall for:', obj);
return new Promise((resolve) => {
setTimeout(() => {
let resolution = obj.body + 5; // change the value in some way, just to show that input !== output
console.log('resolving with:', resolution);
return resolve(resolution);
}, 100);
});
}
Upvotes: 3