Отложите возврат фабрики, пока петля не будет полностью закончена angularjs
Я пытаюсь создать метод, который возвращает массив объектов после получения объектов из API. Проблема в том, что возврат с завода происходит до завершения всех вызовов. Я пытался использовать $q.defer, но он все еще отправляет возврат, прежде чем он будет готов к отправке. Это то, что я придумал до сих пор.
angular.module('watchList').factory('storageService', ['$http', '$q', function ($http, $q) {
storage = {};
storage.getMovies = function () {
var movies = localStorage.getItem('movies');
var movieArray = angular.fromJson(movies);
var newArray = [];
var defer = $q.defer();
angular.forEach(movieArray, function (id) {
newArray.push($http.get(api + id));
});
$q.all(newArray).then(function (response) {
defer.resolve(response);
});
return defer.promise;
}
Это контроллер, с которого я пытаюсь позвонить
angular.module('watchList').controller('watchListController', ['$scope', 'storageService', function ($scope, storageService) {
$scope.movies = storageService.getMovies();
Я хочу, чтобы цикл завершил все, прежде чем он возвращает массив.
2 ответа
Вам не нужно создавать обещание, вы можете просто вернуть обещание, возвращенное $q.all(newArray)
вызов.
Дело в том, что вы не можете ожидать, что получите результат синхронно, когда он станет доступным только асинхронно. Так что вам нужно продолжать с использованием then
:
storage.getMovies = function () {
var movies = localStorage.getItem('movies');
var movieArray = angular.fromJson(movies);
var newArray = movieArray.map(function (id) {
return $http.get(api + id);
});
return $q.all(newArray);
}
storageService.getMovies().then(function(movies) {
$scope.movies = movies;
// ... other code working with $scope.movies
});
Примечание: map
метод делает то, что вы делаете с forEach
, но сразу возвращает массив, что довольно практично.
getMovies немедленно вернется с обещанием. Вы должны использовать "тогда", чтобы ждать этого обещания.
$scope.movies = storageService.getMovies().then((response) => ...)