2017-05-31 5 views
0

Dies ist meine Forderung mit AngularJS:Schleife warten, bis alle Versprechungen vor der nächsten Iteration gelöst werden

for (var i = 0, len = self.Scope.data.length; i < len; i++) 
{ 

     var data = self.Scope.data[i]; 
     var self = this; 
//First asynchronous function 
self.EcritureService.createNewData(data).then(() => { 
     })              
//Second asynchronous function 
self.OperationService.getOperation(data.idOperation).then((operation) => { 

     }) 
//Third asynchronous function 
self.AccountService.getAccount(data.codeCompte).then((compte) => { 
       currentAccount = compte; 
       currentAccount.montant = currentAccount.montant+data.montant; 
     }) 
//Fourth one relies on the third result, So it must be executed sequentially 
self.AccountService.updateAccount(currentAccount).then(() => { 
     })      
} 
// After all fetch loop's promises are resolved I want to execute some instructions here for to update the operation retrieved in the second function. 

Ich mag diese Schleife Iterators warten, bis alle Versprechen, bevor er auf dem nächsten Schritt gelöst werden, als sicher, dass alle Arbeiten fertig sind, zum letzten Funktionalität zu bewegen, die

außerhalb der Schleife bloc residieren
+0

Können Sie * bitte * Ihren Einzug korrigieren? – Bergi

+0

JavaScript ist single-threaded. Die 'for'-Schleife wird abgeschlossen **, bevor eine der ** Versprechungen aufgelöst wird. Die Schleife kann nicht zum Warten gebracht werden. – georgeawg

+0

Sie können Ihre Logik so schreiben, als wäre sie synchron, setzen Sie sie in Funktion und führen Sie diese Funktion über den synchronen Executor [nsynjs] (https://github.com/amaksr/nsynjs) aus. Siehe die Funktion "process()" in einem ähnlichen Beispiel hier: https://github.com/amaksr/nsynjs/blob/master/examples/browser-ajax-seq.js – amaksr

Antwort

0

erstellen Arrays von Versprechungen und verwenden $q.all(promise_array) zu laufen, wenn alle Versprechen gelöst werden

// map array of `$q.all()` promises 
let promises = self.Scope.data.map((data) => { 
    //First asynchronous function 
    let promise_1 = self.EcritureService.createNewData(data).then(() => {}) 
    //Second asynchronous function 
    let promise_2 = self.OperationService.getOperation(data.idOperation).then((operation) => { 

    }) 
    //Third asynchronous function 
    let promise_3 = self.AccountService.getAccount(data.codeCompte).then((compte) => { 
    currentAccount = compte; 
    currentAccount.montant = currentAccount.montant + data.montant; 
    return currentAccount; 
    }).then((currentAccount) => { 
    //return promise of 4th inside `then()` of third 
    return self.AccountService.updateAccount(currentAccount).then(() => {}); 
    }); 

    // this `$q.all()` resolves when this mapped instance of above all resolve 
    return $q.all([promise_1, promise_2, promise_3]); 

}); 

// resolves when all the loop instances of `$q.all()` resolve 
$q.all(promises).then(()=>{ 
    // run completion code here 
}).catch(err=>{ 
    console.log('Something failed in promise chain') 
}) 
+0

Ha - das ist wunderschön :) Das Array von $ q .all ist das dann $ q.all'ed - liebe es :) Viel besser als eine rekursive Schleife! – IrishDubGuy

0

Zunächst würde ich sagen, dass Sie wahrscheinlich nicht wollen, dass diese Dienstleistungen Versprechen sind, da Sie versuchen, die "Versprechen" von ihnen zu umgehen. Die einfachste Lösung wäre also, die Dienste so umzuschreiben, dass sie normal statt über ein Versprechen zurückkehren.

Aber um Ihre Fragen zu beantworten. Zweiter Teil zuerst - der einfachste Weg, um die vierten Versprechen an den dritten zu verbinden ist es gerade in den dritten .then zu setzen, wie folgen aus:

//Third asynchronous function 
self.AccountService.getAccount(data.codeCompte).then((compte) => { 
      currentAccount = compte; 
      currentAccount.montant = currentAccount.montant+data.montant; 
      //Fourth one relies on the third result, So it must be executed sequentially 
      self.AccountService.updateAccount(currentAccount).then(() => { 
    }) 
}) 

Wenn Sie dann Umgang mit jedem Fehler stellen könnten Sie sich entscheiden, die setzen verschachtelte Versprechen in einer .finally-Klausel statt.

Um die Schleife warten zu lassen, sind for-Schleifen dafür nicht ausgelegt. Der einfachste Weg, dies zu erreichen, wäre, eine eigene Schleife zu schreiben und $ q.all zu verwenden, um die Versprechen zusammenzufassen. Sie müssten einen Schleifenzähler im Auge behalten, den Sie in der .then von $ q.all inkrementieren und eine rekursive Funktion verwenden, die ausbricht, wenn die erforderliche Anzahl von Schleifen erledigt ist.

Verwandte Themen