2017-05-31 105 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中增加一个循环计数器,并使用一个递归函数,当所需的循环次数完成时就会发生。

相关问题