Отложите возврат фабрики, пока петля не будет полностью закончена 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) => ...)
Другие вопросы по тегам