2016-08-05 131 views
2

我目前正在使用一个AngularJS控制器,该控制器应该与多个承诺一起工作,并返回一个布尔值。基于这个布尔值,将确定一个结果布尔值。如果所有返回的值都是true,结果将为true,但即使只有一个承诺返回false,结果也将是false。目前我所有的服务/ DAO呼叫都被锁定,如果一个承诺被拒绝,会导致一些麻烦。我想有一个更好的方法来处理这种情况。AngularJS处理多重承诺

控制器代码:

app.controller('PromiseController', ['$scope', 'FirstService', 'SecondService', 'ThirdService', 
    'FourthService', function ($scope, FirstService, SecondService, ThirdService, FourthService) { 

    var vm = this; 

    vm.statusResult = false; 
    vm.statusSecond = null; 
    vm.statusThird = null; 
    vm.statusFourth = null; 
    vm.statusFirst = null; 

    SecondService.getStatus()  
    .then(function(returnData){ 
     vm.statusSecond = returnData; 
    }) 
    .then(function(){ 
     return ThirdService.getStatus(); 
    }) 
    .then(function(returnData){ 
     vm.statusThird = returnData; 
    }) 
    .then(function(){ 
     return FourthService.getStatus(); 
    }) 
    .then(function(returnData){ 
     vm.statusFourth = returnData; 
    }) 
    .then(function(){ 
     return FirstService.getStatus(); 
    }) 
    .then(function(returnData){ 
     vm.statusFirst = returnData; 
    }) 
    .then(function(){ 
     if(vm.statusThird&&vm.statusFourth&&vm.statusFirst&&vm.statusSecond){ 
      vm.statusResult = true; 
     } 

    }); 

    return this; 

}]); 

所以我在寻找一种更好的方式如何处理多个承诺以及如何解决所有的承诺的最终结果。此外,应用程序不应该在处理结果时冻结。


编辑

$q.all@str该解决方案工作正常,最后的结果,但我也需要所有服务的个性化结果。我怎样才能在处理最终结果的同时处理单个值?

+0

可以并行运行的服务? – str

+0

'$ q.all'或'Promise.all'可以并行运行所有这些承诺,然后给你一组结果。 – ste2425

+0

我想你可以通过2回调你的当时的功能,这是成功和错误块。在这两个函数中返回下一个promise对象,并将被拒绝的promise的状态保存在一个变量中,这样执行就不会停止。 – Nirus

回答

7

您可以使用$q.all等待所有承诺:

var promises = [ 
    FirstService.getStatus(), 
    SecondService.getStatus(), 
    ThirdService.getStatus(), 
    FourthService.getStatus(), 
]; 

$q.all(promises) 
    .then(function (serviceResults) { 
     vm.serviceResults = serviceResults; // result of first promise will be available in vm.serviceResults[0] 
     vm.statusResult = serviceResults.every(function (serviceResult) { 
      return serviceResult; 
     }); 
    }) 
    .catch(function() { 
     vm.statusResult = false; 
    }); 
+0

这看起来非常好,但我有一个问题:如果服务返回以下序列'true','true','false','true'不会由于'vm.statusResult = serviceResults.every(function(serviceResult){return_serviceResult; })'行的最后'true'覆盖'false'值;'? – JohnDizzle

+1

如果至少有一个serviceResult为false,则serviceResults.every将返回false。所以不,它不会覆盖。每一个手段每个值都应该返回true。 –

+1

@JohnDizzle不,像oliv37写的。 'serviceResults'是一个数组,其中包含承诺的所有结果(例如'[true,true,false,true]')。并且'every'函数只在*每个*值为真时才返回true。 – str