Angular $ q.all()遇到问题

时间:2017-11-08 13:15:13

标签: javascript angularjs

我有一个正在制作'n'个$ http请求的工厂,为了实现这一点,我使用$ q.all(),所以让我告诉你我的工厂代码。

app.factory('loadBooks',['$http','$q',function($http,$q){
  var promises = [];
    return {

        getBooks : function(category,no){
          for(var i =1; i<=no; i++){
        var deferred = $q.defer();

                 console.log(i + 'request');
                 $http.get(`https://anapioficeandfire.com/api/${category}?page=${i}&pageSize=10`)
                 .then(function(response){
                  deferred.resolve(response);
                  console.log(response);
                })

        .catch(function(response){
          deferred.reject(response);
        })
        
        promises.push(deferred);
      
        }

          return $q.all(promises);
          
        }
      }

}])

这是我从我调用工厂函数的控制器

app.controller('bookController',['$scope','loadBooks','$routeParams',function($scope,loadBooks,$routeParams){
    $scope.count = $routeParams.no;
    loadBooks.getBooks('books',2).then(function(data){
          $scope.books = data;   
       })
       .catch(function(response){
       });
    }]);

现在问题是我从getBooks方法发出2个请求,并且api正在向我发送请求的数据,但由于某种原因,第一个请求不会在promise数组中推送数据,但第二个请求。我不知道我做错了什么。 api工作正常,因为我可以看到我的网络选项卡中的数据,但来自第一个请求的数据没有被推入promise数组! 如果你能告诉我这是什么问题,我将感激不尽。顺便说一下,我是$ q的新手。

1 个答案:

答案 0 :(得分:3)

你已成为一个名为“关闭循环变量”的阴险错误的牺牲品。 deferred变量的值在循环的每次迭代中都会发生变化,因此最终会执行:

deferred.resolve(response);

deferred指的是deferred变量所采用的 last 值。

最重要的是,您正在使用显式承诺创建反模式,这是一种反模式,会导致您的承诺代码不必要地卷曲并且容易出错。

按照应该使用的方式解决这两个问题:

app.factory('loadBooks', ['$http', '$q', function($http, $q) {
  return {
    getBooks: function(category, no) {
      var promises = [];

      for (var i = 1; i <= no; i++) {
        console.log(i + 'request');
        promises.push(
            $http.get(`https://anapioficeandfire.com/api/${category}?page=${i}&pageSize=10`)
        );
      }

      return $q.all(promises);
    }
  }

}])