修改
第一个答案是优雅的答案,但是,正如在这个问题中提到的几次以及有关stackoverflow的另一个问题,问题是服务和控制器在数据实际到达之前运行它们的东西。
(对第一个答案的最后评论:)
是的,问题是API调用在服务运行后完成 并将所有内容返回给控制器,请参见此处 screencast.com/t/uRKMZ1IgGpb7 ...这是我的基本问题,我怎么能 等待数据的所有部分到达?
就像我在重复时说的那样,我们如何在成功的数据检索之后创建一个填充数组的服务,并且控制器在所有这些发生之后获取数据,因为你可以在我的截图中看到,事情以不同的顺序运行。
我有这段代码:
var deferred = $q.defer();
$http.get('../wordpress/api/core/get_category_posts/?category_id=14 ').success(function(data) {
//we're emptying the array on every call
theData = [];
catName = data.category.slug;
theData = data;
theData.name = catName;
aggregatedData.push(theData);
});
$http.get('../wordpress/api/core/get_category_posts/?category_id=15 ').success(function(data) {
theData = [];
catName = data.category.slug;
theData = data;
theData.name = catName;
aggregatedData.push(theData);
});
$http.get('../wordpress/api/core/get_category_posts/?category_id=16 ').success(function(data) {
theData = [];
catName = data.category.slug;
theData = data;
theData.name = catName;
aggregatedData.push(theData);
});
$http.get('../wordpress/api/core/get_category_posts/?category_id=17 ').success(function(data) {
theData = [];
catName = data.category.slug;
theData = data;
theData.name = catName;
aggregatedData.push(theData);
});
//deferred.resolve(aggregatedData);
$timeout(function() {
deferred.resolve(aggregatedData);
}, 1000);
/*//deferred.reject('There is a connection problem.');
if (myservice._initialized) {
$rootScope.$broadcast('postsList', deferred.promise);
}*/
//myservice._initialized = true;
myservice = deferred.promise;
return deferred.promise;
对于我的生活,我无法理解为什么在传递结果数组时要延迟?
不应该原则如何,推迟等待信息然后返回承诺?那1秒有什么意义呢?根据我的理解,延迟应该能够等待API返回结果并返回承诺数据所需的时间。
我真的很困惑,过去两个小时我撞到了墙上,因为我没有在控制器中收到任何数据,只有当我把那个超时放在那里时。
答案 0 :(得分:60)
恕我直言,我认为用$q.all
做一个非常聪明(优雅)的方法。
请查看下面的代码。
我假设您想要立即返回数据,并将所有结果聚合在一个大数组上。
var myApp = angular.module('myApp', []);
myApp.factory('myService', function ($http, $q) {
return {
getAllData: function () {
return $q.all([
$http.get('../wordpress/api/core/get_category_posts/?category_id=14'),
$http.get('../wordpress/api/core/get_category_posts/?category_id=15'),
$http.get('../wordpress/api/core/get_category_posts/?category_id=16'),
$http.get('../wordpress/api/core/get_category_posts/?category_id=17')
]).then(function (results) {
var aggregatedData = [];
angular.forEach(results, function (result) {
aggregatedData = aggregatedData.concat(result.data);
});
return aggregatedData;
});
}
};
});
您可以在上面看到aggregatedData
仅在通过$q.all
完成所有异步调用后生成。
例如,您只需要将服务作为依赖项包含在您的某个控制器中,然后像这样调用服务myService.getAllData()
希望有帮助或只是告诉我你是否需要一个完整的工作示例,我可以提供一个! :)
答案 1 :(得分:11)
$http.get
次呼叫是异步的,但在解决延迟之前,您不会等到它们全部完成。这里的超时工作只是因为你很幸运,电话有时间在1秒内完成,但这根本不可靠。
我不会在此重申完整的解决方案,但请查看my answer以了解其他类似问题。