循环内的 Strongloop 承诺

Strongloop promise inside loop

我正在尝试在 for 循环内调用环回查找函数,将迭代中的值传递给环回函数。代码的主要问题可以表示如下:

for (var a = 0; a < $scope.countries.length; a++) {
  $scope.getEmFacPurElec($scope.countries[a], 'ton/kWh', 'CO2e').then(function(result) {
    emFacPurElecToUse = $scope.emFacPurElecs;
}

这里是被调用的函数:

$scope.getEmFacPurElec = function (country, unit, ghgType) {
   var defer = $q.defer();
   $scope.emFacPurElecs = [];

   $scope.emFacPurElecs = Country.emFacPurElecs({
      id: country.id,
      filter: {
               where: {
                       and: [
                             {unit: unit},
                             {ghgType: ghgType}
                            ]
                      }
              }
   });   

   defer.resolve('Success getEmFacPurElec');
   return defer.promise;
};             

问题是回送承诺函数被调用然后返回未定义,这意味着它在获取分配给 emFacPurElecToUse 的值之前移动到 for 循环的下一次迭代。在移动到下一个国家/地区之前,我需要对该国家/地区的该变量进行更多计算。

我已经考虑过使用 $q.all 作为可能的解决方案,并根据 http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html 使用 array.map(新手错误 #2:WTF,我该如何使用 forEach()有承诺?),但我只是想不出如何将它们组合在一起以使其发挥作用。我应该改用 forEach 吗?

我也看到了这个 link angular $q, How to chain multiple promises within and after a for-loop(以及其他类似的),但我没有需要在 for 循环内处理的多个承诺。我需要为那个国家检索一个 emFacPurElecs 的值,用它做一些工作,然后移动到下一个国家。我觉得我很接近,但我无法理解我将如何编写这个特定功能的代码。非常感谢任何帮助。

在我看来你确实有多个承诺要在你的 for 循环中处理,正如你所说 "I need to do some more calculations with that variable for that country before moving to the next country." 这一切都应该在我建议的承诺链中完成 - calcEmFacPurElec.

$scope.calcEmFacPurElec = function (country, unit, ghgType) {
   $scope.getEmFacPurElec(country, unit, ghgType).then(function(countryEmFacPurElecs) {
    // do something with countryEmFacPurElecs

    return countryEmFacPurElecs;
}

$scope.getEmFacPurElec = function (country, unit, ghgType) {
   var defer = $q.defer();

   defer.resolve(Country.emFacPurElecs({
      id: country.id,
      filter: {
               where: {
                       and: [
                             {unit: unit},
                             {ghgType: ghgType}
                            ]
                      }
              }
   });   );
   return defer.promise;
};      

希望以上是正确方向的指针!

当您想对一组项目执行承诺链时,正如您所确定的那样,Promise.all(使用您需要的任何承诺实现)就是您想要的。 .all 接受一个 Promises 数组,所以在你的 for 循环中你可以这样做:

var promises = []; 
for (var a = 0; a < $scope.countries.length; a++) {
  promises.push($scope.calcEmFacPurElec($scope.countries[a], 'ton/kWh', 'CO2e')); // new promise chain that does all of the work for that country
}

$q.all(promises).then(function(arrayofCountryEmFacPurElecs) {console.log('all countries completed')});