AngularJS 承诺,$q,延迟 [英] AngularJS Promises, $q, defer

查看:34
本文介绍了AngularJS 承诺,$q,延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑

第一个答案是优雅的答案,但是,正如在这个问题和关于 stackoverflow 的另一个问题中所述的几次,问题在于服务和控制器在数据实际到达之前运行它们的东西.

The first answer is the elegant one, but, as stated a few times in this question and another questions on stackoverflow, the problem is that the service and the controller run their thing before the data actually arrives.

(对第一个答案的最后评论:)

(Last comment on the first answer:)

是的,问题是 API 调用在服务运行后完成并将所有内容返回给控制器,请参见此处screencast.com/t/uRKMZ1IgGpb7 ...这是我的基本问题,我怎么能等待数据到达所有部分?

Yes, the problem is that the API calls finish AFTER the service runs and returns everything to the controller, see here screencast.com/t/uRKMZ1IgGpb7 ... That's my BASE question, how could I wait on all the parts for the data to arrive?

这就像我在重复一遍,我们如何制作一个服务,在成功检索数据后填充数组,以及在所有这些发生后控制器获取数据,因为你可以在我的屏幕截图中看到,事情以不同的顺序运行.

It's like I'm saying it on repeat, how do we make a service that populates the array after the successful data retrieval, and the controller getting data after all this happens, because as you can see in my screenshot, things run in a different order.

我有这个代码:

 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 时必须设置超时?

For the life of me I can't understand why do I have to put a timeout when passing the resulting array to defer ?

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

Shouldn't the principle be like, defer waits for the information to come and then returns the promise? What is the point of that 1 second there? From what I understand defer should be able to wait as long as needed for the API to return the result and the return the promised data.

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

I'm really confused, I've banged my head against the walls for the last two hours because I was not receiving any data in my controller, only when I put that timeout there.

推荐答案

恕我直言,我认为使用 $q.all 有一种非常聪明(而且优雅)的方法来做到这一点.

IMHO I think there's a much clever (and elegant) way to do this with $q.all.

请看下面的代码.

我假设您希望将所有结果汇总到一个大数组中一次返回数据.

I am assuming that you want to return the data at once with all the results aggregated on a big array.

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 完成所有异步调用后才会生成.

You can see above that the aggregatedData is only generated once all the async calls are completed via the $q.all.

例如,您只需将该服务作为依赖项包含到您的控制器之一中,然后像这样调用该服务 myService.getAllData()

You just need to include the service as dependency into one of your controllers, for example, and call the service like this myService.getAllData()

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

Hope that helps or just let me know if you need a full working example and I can provide one! :)

这篇关于AngularJS 承诺,$q,延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆