16

编辑

第一个答案是优雅的,但是,正如在这个问题和关于 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;

对于我的一生,我无法理解为什么在将结果数组传递给 defer 时必须设置超时?

原理不应该是这样,defer等待信息到来然后返回promise吗?那1秒有什么意义?据我了解,defer 应该能够等待 API 返回结果并返回承诺的数据所需的时间。

我真的很困惑,过去两个小时我一直把头撞在墙上,因为我没有在控制器中收到任何数据,只有当我在那里设置超时时。

4

2 回答 2

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()

希望对您有所帮助,或者如果您需要一个完整的工作示例,请告诉我,我可以提供一个!:)

于 2013-09-07T15:32:36.340 回答
11

这些$http.get调用是异步的,但您不必等到它们全部完成后再解决延迟。在这里它与超时一起工作,只是因为您很幸运呼叫有时间在 1 秒内完成,但这根本不可靠。

我不会在这里重申一个完整的解决方案,但看看对另一个类似问题的回答。

于 2013-09-07T15:28:52.310 回答