Пока или для цикла с $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
. Он будет выполнен только в том случае, если запрос завершился неудачно. Два первых предупреждения будут выполнены, если запрос пройдет ИЛИ третий будет запущен, если он сработает.