Подтвердить что ты не робот

Передача переменной в обещание в цикле

У меня есть обещание в цикле, и я не знаю, как передать некоторые переменные области видимости в обработчик обещаний.

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 logicaly не отображает 1,2,3,4,5. Но 5,5,5,5,5. (в моем супераррейте есть 5 элементов).

Как я могу передать значение "i" в области моего обещания, поэтому я могу использовать его в then()?

Возможно ли это?

4b9b3361

Ответ 1

Одним из способов является захват 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);
    });
};

Ответ 2

К моменту выполнения вашего обратного вызова i будет ссылаться на последний элемент в вашем массиве. Вы можете использовать закрытие и зафиксировать текущее значение i:

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

Ответ 3

Вы можете немного упростить код, используя встроенный Array.prototype.forEach:

superarray.forEach(function (item, index) {
    MyService.get(item.externalID).then(function(r) {
        console.debug(index);
    });
});

Ответ 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.