当前位置: 首页 > 知识库问答 >
问题:

在初始化控制器之前解析路由解析中的多个promise

裴彦
2023-03-14

我有两个http调用需要在初始化我的控制器之前重新启动,目前使用Angular UI路由器,我有$stateProvider下的resolve map。状态('stateName',{stateObject})我的状态对象如下

    $stateProvider.state('stateName', {
        url  : '/myURL',
        params: {
                 data1: undefined,
                 data2 : undefined
            },
        resolve: {
            dataTobeResolve : function($stateParams,$q) {

                var deferred = $q.defer();
                var deferredObj = {};
                deferredObj.d1 = $q.defer();
                deferredObj.d2 = $q.defer();

                var result = {
                    data1: {},
                    data2: {}
                }

                if(angular.isDefined($stateParams.data1)) {
                    result.data1 = $stateParams.data1;
                    deferredObj.d1.resolve();
                }
                else {
                    httpCall().then(function(response) {
                        AsyncMethodCall(response.data).then(function(resolvedData) {
                            result.data1 = resolvedData;
                            deferredObj.d1.resolve();       
                        });
                    });
                }

                if(angular.isDefined($stateParams.data2)) {
                    result.data2 = $stateParams.data2;
                    deferredObj.d2.resolve();
                }
                else {
                    AsyncMethodCall().then(function(resolvedData) {
                        result.data2 = resolvedData;
                        deferredObj.d2.resolve();       
                    });
                }

                $q.all(deferredObj).then(function() {
                    deferred.resolve(result);
                });
                return deferred.promise;
            }
        }
    });

不管怎么说,尽管有了德雷多布。d1作为resolve controll转到$q.all(deferredObj)的(function(){}),这是一个意外的行为,我相信在执行此行之前,应该解析deferredObj的所有promise映射,我的控制器得到初始化,尽管其中一个promise已被解析

共有2个答案

支才
2023-03-14

我发现了这个问题,这是由于将延迟对象传递到$q.all()而不是promise的哈希/数组。所以下面的代码将解决这个问题

$stateProvider.state('stateName', {
    url  : '/myURL',
    params: {
             data1: undefined,
             data2 : undefined
        },
    resolve: {
        dataTobeResolve : function($stateParams,$q) {

            var deferred = $q.defer();
            var promises = {};
            var d1 = $q.defer();
            var d2 = $q.defer();
            promises.d1 = d1.promise;
            promises.d2 = d2.promise;

            var result = {
                data1: {},
                data2: {}
            }

            if(angular.isDefined($stateParams.data1)) {
                result.data1 = $stateParams.data1;
                d1.resolve();
            }
            else {
                httpCall().then(function(response) {
                    AsyncMethodCall(response.data).then(function(resolvedData) {
                        result.data1 = resolvedData;
                        d1.resolve();       
                    });
                });
            }

            if(angular.isDefined($stateParams.data2)) {
                result.data2 = $stateParams.data2;
                d2.resolve();
            }
            else {
                AsyncMethodCall().then(function(resolvedData) {
                    result.data2 = resolvedData;
                    d2.resolve();       
                });
            }

            $q.all(promises).then(function() {
                deferred.resolve(result);
            });
            return deferred.promise;
        }
    }
});

但我还是很感激有人能提供更好的解决方案

吴山
2023-03-14

因为$q.all$超文本传输协议. so方法都返回promise,所以不需要用$q.defer制造promise。仅使用$q.defer从旧风格的仅回调异步API中做出promise。

使用$q.when从同步源或AngularJS框架外部作出promise。

resolve: {
    dataTobeResolve : function($stateParams,$q) {

        var d1Promise;
        var d2Promise;

        if(angular.isDefined($stateParams.data1)) {
            d1Promise = $q.when($stateParams.data1);
        }
        else {
            d1Promise = httpCall()
              .then(function(response) {
                   return response.data;
            });
        }

        if(angular.isDefined($stateParams.data2)) {
            d2Promise = $q.when($stateParams.data2)
        }
        else {
            d2Promise = httpCall2()
              .then(function(response) {
                  return response.data;      
            });
        }

        return $q.all([d1Promise, d2Promise]);
    }
}

在上述示例中,两个promise是由参数的$q.when创建的,或者是从基于promise的异步API派生的。复合promise是用$q.all方法从两个promise中创建的。

使用派生promise的优点是拒绝会自动结转到最终promise。当前编写的$q.defer方法将挂起状态更改,如果其中一个XHR调用有来自服务器的错误。

 类似资料:
  • 问题内容: 我已经尽一切努力让ui路由器解析将其值传递给给定的控制器AppCtrl。我正在使用依赖注入,这似乎引起了问题。我想念什么? 路由 控制者 编辑 这是一个小家伙http://plnkr.co/edit/PoCiEnh64hR4XM24aH33?p=preview 问题答案: 在将路由解析参数用作绑定到该路由的控制器中的依赖项注入时,由于名称不存在的服务提供程序,因此不能将该控制器与ng-

  • 本文向大家介绍实例解析Java中的构造器初始化,包括了实例解析Java中的构造器初始化的使用技巧和注意事项,需要的朋友参考一下 1.初始化顺序   当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序开始对这些实例属性执行初始化,其初始化顺序是:先执行初始化块或声明属性时制定的初始值,再执行构造器里制定的初始值。 在类的内部,变量定义的先后顺序决定了

  • 问题内容: 我正在尝试建立一个视图-我设置了两个控制器进行练习,一个是HeaderCtrl,其中包含一些数据(网站标题,标题背景等),另一个应该具有页面的主要内容- MainCtrl。 在定义路线时,我这样做是: 这工作得很好,但是我想要为此指定多个参数,如下所示: 这行不通,所以我猜这不是做到这一点的方法。我实际上要问的是-您可以在$ routeProvider中指定多个控制器吗?还是构建此视图

  • 问题内容: 我有一个AngularJs应用程序,我想在其中一开始就加载消息和应用程序版本,并将它们保存在本地存储中,然后再在控制器中使用它们。我现在所拥有的是每个控制器中的服务调用(目前为三个): 我只想获取一次应用程序版本并将其存储在此处。我不必每次都检查版本,对(如果新版本中添加了新消息)? 我发现使用$routeProvider的建议,但我的应用程序不是SPA。所以我需要其他想法/建议。对你

  • 本文向大家介绍C++直接初始化与复制初始化的区别深入解析,包括了C++直接初始化与复制初始化的区别深入解析的使用技巧和注意事项,需要的朋友参考一下 C++中直接初始化与复制初始化是很多初学者容易混淆的概念,本文就以实例形式讲述二者之间的区别。供大家参考之用。具体分析如下: 一、Primer中的说法 首先我们现来看看经典是怎么说的: “当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始

  • 问题内容: 我有3个执行类似任务的控制器: PastController 向API查询过去的系统中断。 CurrentController 向API查询当前系统中断 FutureController 向API查询将来的系统中断 它们每个都是唯一的(尽管它们具有相似的功能)。但是,它们都从定义相同的变量开始: 我可以使用服务或工厂在一处初始化这些变量,而不用重复代码吗? 问题答案: 我没有测试代码,