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