我有一个正在制作'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的新手。
答案 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);
}
}
}])