2015-07-15 3 views
24

Ich habe eine Schleife, die eine Methode aufruft, die asynchornous tut. Diese Schleife kann die Methode viele Male aufrufen. Nach dieser Schleife habe ich eine andere Schleife, die nur ausgeführt werden muss, wenn alle asynchronen Dinge erledigt sind. So das meine Wünsche veranschaulichen:Wie man viele Promises in einer Schleife zurückgibt und darauf wartet, dass alle andere Sachen machen

Ich bin nicht so vertraut mit Versprechungen so könnte mir jemand helfen, dies zu erreichen? Diese

ist, wie mein doSomeAsyncStuff() verhalten:

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

Vielleicht habe ich so etwas zu tun:

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

Aber ich bin der Syntax nicht sicher.

+0

Steuern Sie die asynchronen Anrufe? Geben sie bereits Versprechungen zurück, oder können Sie ihnen Versprechen geben? –

+0

Was genau ist die Sequenz? Müssen Sie die anderen Funktionen aufrufen, nachdem * alle * die vorherigen asynchronen beendet sind? Oder müssen Sie nur eine Funktion aufrufen, nachdem alle Asyncs beendet sind? – Sosdoc

+0

Momentan gibt die erste Funktion keine Versprechen zurück. Das muss ich umsetzen. Ich möchte meine Nachricht bearbeiten, um einige Details zum Workflow meiner Funktionen hinzuzufügen. Und ja, ich brauche, dass alle Sachen der ersten Schleife beendet werden, bevor ich anfange, das Zeug in der zweiten Schleife auszuführen. – Ganbin

Antwort

43

können Sie verwenden Promise.all (spec, MDN) dafür: Es hat eine Reihe von individuellen Zusagen akzeptiert und gibt Ihnen wieder ein einziges Versprechen, das gelöst wird, wenn alle diejenigen, gibt man sich aufgelöst werden, oder abgelehnt, wenn einer von ihnen ist abgelehnt.

Also, wenn Sie doSomeAsyncStuff Rückkehr ein Versprechen zu machen, dann:

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 hat einen guten Artikel auf Versprechungen here.

Hier ist ein Beispiel - 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();

(Haben Sie nicht mit .catch auf, dass die Mühe, aber Sie tun .catch auf Ihrer realen Welt diejenigen wollen, wie bereits gezeigt.)

Probenausgabe (wegen der Math.random, welche Ausführungen zuerst abweichen können):

 
Resolving 3 
Resolving 2 
Resolving 1 
Resolving 4 
Resolving 0 
All done [0,1,2,3,4] 
+0

Ok danke das versuche ich jetzt und ich komme mit Feedback in wenigen Minuten. – Ganbin

+7

Wow, vielen Dank, jetzt verstehe ich viel mehr die Versprechen.Ich lese viel über Versprechen, aber bis wir sie in echten Code verwenden müssen, verstehen wir nicht wirklich alle Mechanismen. Jetzt bekomme ich es besser und ich kann anfangen, coole Sachen zu schreiben, dank dir. – Ganbin

+0

Wirklich hilfreich, danke! – Lucy