2015-07-15 13 views
24

Ho un ciclo che chiama un metodo che fa roba asincrona. Questo ciclo può chiamare il metodo molte volte. Dopo questo ciclo ho un altro ciclo che deve essere eseguito solo quando tutte le cose asincrone sono fatte. Quindi questo illustra le mie esigenze:Come restituire molte promesse in un ciclo e attendere che tutti facciano altre cose

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

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

Non mi sono familiare così tanto con le promesse, quindi qualcuno potrebbe aiutarmi a raggiungere questo obiettivo?

Ecco come il mio doSomeAsyncStuff() si comportano:

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

Forse devo fare qualcosa di simile:

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

Ma io non sono sicuro della sintassi.

+0

Hai il controllo delle chiamate asincrone? Rendono già le promesse, o puoi farle restituire promesse? –

+0

Che cos'è esattamente la sequenza? Hai bisogno di chiamare le altre funzioni dopo che * tutti * i precedenti asincroni sono finiti? O hai solo bisogno di chiamare una funzione dopo che ognuna delle async è finita? – Sosdoc

+0

Per ora la prima funzione non restituisce promesse. Che devo attuare. Voglio modificare il mio messaggio per aggiungere alcuni dettagli del flusso di lavoro delle mie funzioni. E sì, ho bisogno che tutte le cose del primo ciclo finiscano prima di iniziare ad eseguire il materiale nel secondo ciclo. – Ganbin

risposta

43

È possibile utilizzare Promise.all (spec, MDN) per questo: Si accetta una serie di singole promesse e restituisce un singolo promessa che si risolve quando tutti quelli che hai dato vengono risolti, o rifiutata quando uno di essi è respinto

Quindi, se si effettua doSomeAsyncStuff ritorno una promessa, quindi:

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 ha un buon articolo su promesse here.

Ecco un esempio - 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();

(non si è preoccupato con .catch su questo, ma si vuole .catch sui vostri reali, come illustrato in precedenza.)

Esempio di output (a causa del Math.random, cosa finisce per primo può variare):

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

Ok grazie, ci provo ora e arrivo con un feedback in pochi minuti. – Ganbin

+7

Wow, grazie mille, ora capisco molto di più le promesse. Leggo molto sulle promesse, ma finché non avremo bisogno di usarle nel codice reale, non capiamo veramente tutti i meccanismi. Ora ho capito meglio e posso iniziare a scrivere cose interessanti, grazie a te. – Ganbin

+0

Davvero utile, grazie! – Lucy

Problemi correlati