38

我在循环中有一个承诺,但我不知道如何将一些范围变量传递给承诺处理程序。

for(var i in superarray){
    MyService.get(superarray[i].externalID).then(function(r){
        console.debug(i);
});

MyService 是一个工作服务,带有一个返回承诺的 get 方法。

app.factory('MyService', function($http,$q) {
  return {
     get : function(itemID){
        var deferred = $q.defer();
        $http.get('/someresturl/'+itemID).then(function(e) { 
                deferred.resolve(e.data);
        }, function(reason) {
                deferred.reject(reason);
        });
        return deferred.promise;
    }
});

在我的控制台中,console.debug 逻辑上不显示 1、2、3、4、5。但是5,5,5,5,5。(我的超级数组中有 5 个元素)。

如何在我的承诺范围内传递 'i' 值,以便在 then() 中使用它?

可能吗?

4

5 回答 5

78

一种方法是i在闭包中捕获:

for(var i in superarray) {
    (function(i) {
        MyService.get(superarray[i].externalID).then(function(r) {
            console.debug(i);
        });
    })(i);
}

另一种方法是安排itemID作为 的属性重复返回r

for(var i in superarray){
    MyService.get(superarray[i].externalID).then(function(r) {
        console.debug(r.itemID);
    });
};
于 2013-06-21T21:43:18.717 回答
15

到您的回调运行时,i将引用数组中的最后一个元素。您可以使用闭包并捕获 的当前值i

for (var i in superarray){
    (function(j) {
        MyService.get(superarray[j].externalID).then(function(r) {
            console.debug(j);
        });
    })(i);
}
于 2013-06-21T21:40:02.870 回答
5

您可以使用内置的代码稍微简化一下代码Array.prototype.forEach

superarray.forEach(function (item, index) {
    MyService.get(item.externalID).then(function(r) {
        console.debug(index);
    });
});
于 2013-06-24T00:39:13.150 回答
4

我只是对接受的解决方案发表评论,但我目前没有足够的声誉。

我认为将 itemID 重复为 r 的属性的第二种解决方案也可以正常工作。

简单的承诺处理程序:

angular.module('myApp', []).run(['MyService', function(MyService) {
  superarray = [1, 2, 3, 4, 5];


  for(var i in superarray) {
    MyService.get(superarray[i]).then(function(returned) {
      console.log(returned.id);
    });
  }

}]);

MyService 返回 itemID 作为返回对象的属性:

angular.module('myApp')
.factory('MyService', function($http,$q) {
  return {
     get : function(itemID){
        var deferred = $q.defer();

        $http.get('www.google.com').then(function(e) { 
                var returnObject = {
                  'data': e.data,
                  'id': itemID
                };
                deferred.resolve(returnObject);
        }, function(reason) {
                deferred.resolve(reason);
        });
        return deferred.promise;
    }
}});

这是一个关于 plnkr的工作示例。

于 2014-08-20T07:50:22.943 回答
2

试试这个解决方案,我使用了 $q.all 并将我的参数添加到数组中。有效

   for(var i in superarray){
      $q.all([MyService.get(superarray[i].externalID), i]).then(function(results){
        var r = results[0];
        var i = results[1];
        console.debug(i);
      });
    }
于 2018-03-19T10:14:18.947 回答