Jak zwracać wiele obietnic w pętli i czekać, aż wszystkie zrobią inne rzeczy

Mam pętlę, która wywołuje metodę, która robi rzeczy asynchronicznie. Pętla ta może wywołać metodę wiele razy. Po tej pętli mam inną pętlę, która musi być wykonywana tylko wtedy, gdy wszystkie asynchroniczne rzeczy są wykonane. Więc to ilustruje moje pragnienia:

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

for(i=0;i<5;i++){
    doSomeStuffOnlyWhenTheAsyncStuffIsFinish();    
}
Nie znam się za bardzo na obietnicach, więc czy ktoś mógłby mi w tym pomóc?

Tak zachowują się moje doSomeAsyncStuff():

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

Może muszę coś takiego zrobić:

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

Ale nie jestem pewien składnia.

Author: Ganbin, 2015-07-15

1 answers

Możesz użyć Promise.all (spec, MDN) za to: przyjmuje kilka indywidualnych obietnic i oddaje ci jedną obietnicę, która jest rozwiązana, gdy wszystkie te, które jej dałeś, są rozwiązane, lub odrzucona, gdy któreś z nich jest odrzucone.

Więc jeśli złożysz doSomeAsyncStuff zwróć obietnicę, to:

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 ma dobry artykuł na temat obietnic tutaj .

Oto przykład - live copy na 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();

(Nie zawracał sobie tym głowy .catch, ale chcesz .catch na swoich prawdziwych, jak pokazano wcześniej.)

Przykładowe wyjście (ze względu na Math.random, to, co kończy się najpierw, może się różnić):

Resolving 3
Resolving 2
Resolving 1
Resolving 4
Resolving 0
All done [0,1,2,3,4]
 69
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 17:09:25