2

I'm not looking for any solution in any particular language, I just want to understand what are the good practices in the area of running async tasks from a loop.

This is what I have thought of so far:

var callAcc = 0;
var resultArr = [];

for (var k = 0; k < 20; k++) {
    callAcc ++;

    asyncFunction("variable")
        .then(function (result) {
            resultArr.push(result);

            if (callAcc === resultArr.length) {
                // do something with the resultArr
            }
        })
        .catch(function (err) {
           console.warn(err);
        });
}

At this point, I'm just using a sync variable that will only let me proceed once I have all of the async tasks complete. However, this feels hacky and I was wondering if there was some kind of design pattern to execute aync tasks from a loop

EDIT: Based on the proposed solutions, this is what i ended up using

var promises = []; 
for (var i = 0; i < 20; i ++) { 
    promises.push(asyncFunction("param")); 
} 

Promise.all(promises) 
   .then(function (result) { 
     console.log(result); 
   })
   .catch(function (err) { 
     console.warn(err); 
   });

Thank you everyone!

1

1 Answer 1

2

Instead of running your async tasks within a loop, you can abstract away the task of waiting on all your promises by using the Promise.all function, which will take an iterable of your promises and create a new promise which will return an array with all of their results in the same order as the original list of promises as soon as all of them resolve, or fail if any of them fails. Most languages which have Promises have a function like that, and if there isn't, it shouldn't be too hard to define.

If you need all of your promises to run even if any of them fails, you can write a function that does that too, you'd just need to define what to do with the failed Promises (discard them, return the errors somehow...).

Anyway, the gist of it is that the best way of dealing with orchestration of multiple Promises is to define a function which will take all the Promises you need to deal with and return a new Promise which will handle the orchestration.

Something like:

orchestratePromises(promiseList) {
  return new Promise((resolve, reject) => {
    // set up
    for (let promise of promiseList) {
      // define how to handle your promises when they resolve
      // asynchronously resolve or reject
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah this is my solution from your descriptionvar promises = []; for (var i = 0; i < 20; i ++) { promises.push(asyncFunction("param")); } Promise.all(promises) .then(function (result) { console.log(result); }).catch(function (err) { console.warn(err); });