Ganbin Ganbin - 1 year ago 74
Javascript Question

How to return many Promises in a loop and wait for them all to do other stuff

I have a loop which call a method that do stuff asynchornously. This loop can call the method many time. After this loop I have another loop that need to be execute only when all the asynchronous stuff is done. So this illustrate my wants :

for(i=0;i<5;i++){
doSomeAsyncStuff();
}

for(i=0;i<5;i++){
doSomeStuffOnlyWhenTheAsyncStuffIsFinish();
}


I'm not familiar so much with promises so could anyone help me to achieve this?

This is how my
doSomeAsyncStuff()
behave :

doSomeAsyncStuff{
var editor = generateCKEditor();
editor.on('instanceReady',function(evt){
doSomeStuff();
// There should be the resolve() of the promises I think.
})
}


Maybe I have to do something like that :

doSomeAsyncStuff{
var editor = generateCKEditor();
return new Promises(function(resolve,refuse){
editor.on('instanceReady',function(evt){
doSomeStuff();
resolve(true);
})
}
}


But I'm not sure of the syntax.

Answer Source

You can use Promise.all (spec, MDN) for that: It accepts a bunch of individual promises and gives you back a single promise that is resolved when all of the ones you gave it are resolved, or rejected when any of them is rejected.

So if you make doSomeAsyncStuff return a promise, then:

var promises = [];

for(i=0;i<5;i+){
    promises.push(doSomeAsyncStuff());
}

Promise.all(promises)
    .then(() => {
        for(i=0;i<5;i+){
            doSomeStuffOnlyWhenTheAsyncStuffIsFinish();    
        }
    })
    .catch((e) => {
        // handle errors here
    });

Axel Rauschmayer has a good article on promises here.

Here's an example - live copy on Babel's REPL:

function doSomethingAsync(value) {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Resolving " + value);
      resolve(value);
    }, Math.floor(Math.random() * 1000));
  });
}

function test() {
  let i;
  let promises = [];

  for (i = 0; i < 5; ++i) {
    promises.push(doSomethingAsync(i));
  }

  Promise.all(promises)
      .then((results) => {
        console.log("All done", results);
      })
      .catch((e) => {
          // Handle errors here
      });
}

test();

(Didn't bother with .catch on that, but you do want .catch on your real-world ones, as shown earlier.)

Sample output (because of the Math.random, what finishes first may vary):

Resolving 3
Resolving 2
Resolving 1
Resolving 4
Resolving 0
All done [0,1,2,3,4]
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download