将参数传递给 $q.all 回调

Pass parameter to $q.all callback

我需要将一些本地参数传递给 $q.all 回调

var actions = [];
var jsonFiles = ["a.json","b.json","c.json"];

for(var index=0; index<3; index++){
    actions.push($http.get('content/' + jsonFiles[index]);
}

$q.all(actions).then(function (values) {
    console.log(index) // Need to print current request index
}

当前输出当然是3,3,3
我需要按照响应顺序打印0,1,2(可以是1,0,2或者其他组合)

我已经针对我的问题创建了一个 jsfiddle - http://jsfiddle.net/dorcohen/n30er4ap/

好吧,所以有点矫枉过正,但我​​认为它会起作用

for(var index=0; index<3; index++){
    actions.push($q.all([
       $q.resolve(index),
       $http.get('content/' + jsonFiles[index]);
    ]);
}

如果我理解正确,你应该使用 params :

  for (var index = 0; index < 3; index++) 
   {
    actions.push($http.get( jsonFiles[index], {params:{"idx": index }}));
   }

然后:

   $q.all(actions).then(function(values) {
     for (var i=0;i<values.length;i++)
       $scope.indexes.push(values[i].config.params.idx); 
    })

Fiddle

虽然@Royi 的回答是正确的,但 if 不适用于 "non-http" 承诺。

一个很好的解决方法,适用于某种承诺,是使用 anti-pattern 创建一个 defered 对象作为包装器并解析您自己的自定义对象。

虽然这是 anti-pattern,但在某些情况下您希望像此处那样使用它。

HTML:

<div ng-app="app">
  <div ng-controller="ctrl">
    <button ng-click="do()">
      Click
    </button>
  </div>
</div>

JS:

angular.module('app', []).
controller('ctrl', function($scope, $http, $q) {
  $scope.do = function() {
    var acts = [];

    for (var i = 0; i < 3; i++) {
      var defer = $q.defer(); // create your own deferred object

     // worked with a dummy promise - you can use what ever promise you want
      var promise = $q.when({
        obj: i
      });


      promise.then(
        // closure for the current deferred obj + index since we are in a loop
        function(d,idx) {
          return function(item) {
            d.resolve({res: item, index:idx}); // resolve my deferred object when I want and create a complex object with the index and the "real response"
          }
        }(defer,i));

      acts.push(defer.promise);
    }
    $q.all(acts).then(function(res) {
      console.log(res);
    });
  }
});

JSFIDDLE.