2017-05-31 38 views
0

這是我與AngularJS要求:循環等到所有的承諾都是下一次迭代之前解決

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. 

我想這個循環迭代等到所有的承諾纔去下一步不是確保所有被解決作品完成後,移動到駐留在環集團外

+0

你能*請*修理你的縮進? – Bergi

+0

JavaScript是單線程的。在任何**的承諾解決之前,for循環將完成**。循環不能等待。 – georgeawg

+0

你可以編寫你的邏輯,就好像它是同步的,放到函數中,並通過同步執行器[nsynjs](https://github.com/amaksr/nsynjs)執行該函數。在類似的例子中看到函數「process()」:https://github.com/amaksr/nsynjs/blob/master/examples/browser-ajax-seq.js – amaksr

回答

0

創建承諾的陣列和使用$q.all(promise_array)運行時,所有的承諾都解決了最後的功能

// 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

哈 - 這是美麗的:) $ q所有這一切都是$ q.all'ed - 愛它:)比遞歸循環好得多! – IrishDubGuy

0

首先,我想說你可能不希望這些服務是承諾,因爲你試圖繞過它們的「承諾」。所以最簡單的解決方案是將服務重寫爲正常返回而不是通過承諾。

但要回答你的問題。第二部分,第一 - 到4諾言鏈接到第三個最簡單的方法就是把它放在第三。那麼裏面,像這樣:

//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(() => { 
    }) 
}) 

如果你把任何錯誤,然後處理你可能會決定把而是在一個.finally子句中嵌套承諾。

至於讓循環等待,for循環實際上不是爲了做到這一點。最簡單的方法是編寫自己的循環,並使用$ q.all將承諾組合在一起。你需要跟蹤一個循環計數器,在$ q.all中增加一個循環計數器,並使用一個遞歸函數,當所需的循環次數完成時就會發生。

相關問題