无法在for循环中得到求和

时间:2017-02-16 02:17:18

标签: javascript angularjs for-loop

我在angular service内有一个for loop,它返回一个对象数组。我想得到service返回的值的总和,但最后我什么也没得到。我的服务工作正常但我的问题是我无法得到总结。以下是我的代码

控制器

var TotalOBValueLand = 0;
for(var i = 0; i < $scope.selectedProp.length; i++){
     AccountService.getTopAccountDetails($scope.selectedProp[i]["propId"]).then(function(msg){
           TotalOBValueLand += parseInt(msg.data[0].OBValueLand);
           //my return data here has no error.
     });
}
console.log(TotalOBValueLand); //I got zero;

3 个答案:

答案 0 :(得分:3)

使用Promise.allarray#map获取结果数组,然后使用Array#reduce来总结它们

var TotalOBValueLand = 0;
Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0].OBValueLand);
     });
})).then(function(results) {
    TotalOBValueLand = results.reduce(function(a, b) {
       return a + b; 
    });
    console.log(TotalOBValueLand);
});
  

回应评论

var TotalOBValueLand = 0;
var TotalOBValueBuilding = 0;
Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0]);
     });
})).then(function(results) {
    TotalOBValueLand = results.reduce(function(a, b) {
       return a.OBValueLand + b.OBValueLand; 
    });
    TotalOBValueBuilding  = results.reduce(function(a, b) {
       return a.OBValueBuilding  + b.OBValueBuilding ; 
    });
    console.log(TotalOBValueLand, TotalOBValueBuilding);
});
  

和更通用的

Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0]);
     });
})).then(function(results) {
    var totals = results.reduce(function(result, a) {
        Object.keys(a).forEach(function(key) {
            result[key] = (result[key] || 0) + a[key];
        });
        return result;
    }, {});
    console.log(totals.OBValueLand, totals.OBValueBuilding);
});

答案 1 :(得分:1)

由于console.log(TotalOBValueLand);是异步的,因此您无法在响应之外访问.getTopAccountDetails(),它始终为0.

尝试将其包裹在内,

var TotalOBValueLand = 0;
for(var i = 0; i < $scope.selectedProp.length; i++){
     AccountService.getTopAccountDetails($scope.selectedProp[i]["propId"]).then(function(msg){
           TotalOBValueLand += parseInt(msg.data[0].OBValueLand);
           console.log(TotalOBValueLand);  
     });
}

答案 2 :(得分:0)

问题是您正在混合异步和同步功能。这应该证明你的一点点

https://jsfiddle.net/Austio/v7goqk4d/

AccountService = {
  getTopAccountDetails: function() {
    return new Promise((resolve) => resolve(1))
  }
}

var TotalOBValueLand = 0;
for(var i = 0; i < 2; i++){
     AccountService.getTopAccountDetails().then(function(x){
       TotalOBValueLand += x;
       console.log('incremented async', TotalOBValueLand)
     });
}
console.log('sync', TotalOBValueLand);
setTimeout(() => 
console.log('timeout', TotalOBValueLand), 2000)

使用我们解决的承诺数组的解决方案

var TotalOBValueLand = 0;
promises = []
for(var i = 0; i < 2; i++){
  promise = AccountService
    .getTopAccountDetails()
  promises.push(promise)
}
console.log('before', TotalOBValueLand);

Promise
  .all(promises)
  .then(results => {
    TotalOBValueLand = results.reduce((curr,acc) => curr + acc, 0);
    console.log('done', TotalOBValueLand);
    return TotalOBValueLand;
  })
  .catch(err => 'handle me')