Пока или для цикла с $http.get

Я хотел бы знать, можно ли использовать while или for с вложенным вызовом $http.get:

Это пример:

for (var i = 0; i < $scope.comments.length; i++) {
   alert($scope.comments[i].id); // = 2
   $http.get('/api/logged/like/isliked?id=' + $scope.comments[i].id).success(function(data, status, header, config) {
        alert('Test');
        alert($scope.comments[i].id); // Not executed.
   }).error(function(data){alert('The requeste isn't working');}); }

Я помещаю два alert для отображения идентификатора моего комментария, который я использую для извлечения JSON. Я получаю идентификатор с первым предупреждением, затем "Тест" для второго, но третье предупреждение не отображается. Почему бы и нет?

Вот пример JSON:

{data ": [{" id ": 2," is_liked ": false," nb_comments ": 1," nb_likes ": 1," date_creation ":" 2014-05-26T17: 03: 54 + 0000 "}, {" id ": 1," is_liked ": true," nb_comments ": 0," nb_likes ": 1," date_creation ":" 2014-05-26T17: 00: 26 + 0000"}]}

Ответ 1

Проблема:

Не выполняйте функции внутри цикла...

Каждый вызов вашей функции на самом деле ссылается на ту же копию i в памяти. Новое закрытие создается каждый раз, когда цикл for работает, но каждый из них захватывает одну и ту же среду. Поэтому каждый вызов $http.get (асинхронная функция) приводит к срабатыванию обратного вызова, ссылающегося на то же конечное значение i с конца цикла.

Решение:

Передайте i в качестве параметра отдельно определенной функции:

var getIsLiked = function(i){
  $http.get('isliked.json' + $scope.comments[i].id)
    .success(function(data) {
      console.log('Test');
      console.log('i is ', i);
      console.log($scope.comments[i].id);
  }).error(function(data){console.log("The request isn't working");}); }
}

for (var i = 0; i < $scope.comments.length; i++) {
  getIsLiked(i);
}

Демо-версия

Это может быть очень сложно обернуть вокруг вас, но это стоит времени, чтобы глубоко понять. Это не только поможет вам избежать подобных проблем в будущем, но также даст вам лучшее представление о закрытии, важной концепции в JavaScript.

Ответ 2

Третье предупреждение находится внутри обратного вызова error вашего обещания $http.get. Он будет выполнен только в том случае, если запрос завершился неудачно. Два первых предупреждения будут выполнены, если запрос пройдет ИЛИ третий будет запущен, если он сработает.