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

如何在复杂的资源加载序列中正确地连锁promise?

赵雪峰
2023-03-14

在angular code中,我有一个像这样的promise:

// a function in LoaderService module.
var ensureTypesLoaded= function(){
   return loadContainerTypes($scope).then(loadSampleTypes($scope)).then(loadProjectList($scope)).then(loadSubjectTypes($scope));
 }

这些函数中的每一个都返回一个promise,该promise从资源中加载东西,并在错误和成功时另外修改$action,例如:

         var loadProjectList = function ($scope) {

            // getAll calls inside a resource method and returns promise.
            return   ProjectService.getAll().then(
                function (items) {
                   // succesfull load
                    console.log("Promise 1 resolved");
                    $scope.projectList = items; 
                }, function () {
                    // Error happened
                    CommonService.setStatus($scope, 'Error!');
                });
        };

我打算在控制器初始化的代码中使用in:

// Part of page's controller initialization code
LoaderService.ensureTypesLoaded($scope).then(function () {
            // do something to scope when successes
             console.log("I will do something here after all promises resolve");
            }, function () {
            // do something when error 
            });

然而,这并不像我想的那样有效。理想情况下,“我会在这里做一些事情后,所有的promise解决”的消息必须出现在所有promise解决。相反,我可以看到它出现在ensureTypesLoaded列出的函数中的已解析promise的消息之前。

我想创建一个函数ensureTypeLoade这样,即:

  • 它返回一个promise,当所有链式负载被解析时,该promise被解析;
  • 如果任何内部promise失败,函数不应该继续下一次调用,而是返回被拒绝的promise。
  • 显然,如果我调用ensureTypeLoed().然后(...),那么()中的东西必须在ensureTypeLoade中的所有内容都解决后调用。

请帮助我正确建立连锁promise。

共有1个答案

拓拔意
2023-03-14

我认为问题出在loadProjectList函数中。因为然后()应该接收在结果生成时调用的函数。通常是函数返回链promise。

但在您的情况下,您立即并行调用所有加载。通过$scope有点复杂。但我认为你的代码应该是这样的

//this fn is called immediatly on chain creation
var loadProjectList = function ($scope) {  
     //this fn is called when previous promise resolves
     return function(data) {
          //don't add error handling here
          ProjectService.getAll().then(...)
     }
}

这可能会导致串行加载。(请注意:对于正确的并行执行,使用了$q.all)

最后,您应该只在ensureTypeLoade中使用错误处理程序,而不是在每个promise中。

 类似资料:
  • 问题内容: 如何在Clojure程序中加载程序资源,例如图标,字符串,图形元素,脚本等?我使用的项目布局类似于许多Java项目中的布局,在Java项目中,“资源”目录挂在“源”目录上。一个jar文件是从源代码创建的,包括资源,但是我似乎无法像在Java中那样加载资源。 我尝试的第一件事是 但是永远找不到资源。 您可以使用类似的方法 其中name是要加载的资源的名称,而流是。 您可以尝试将上下文类加

  • 问题内容: 我知道还有其他针对同一问题的问题,但问题是解决方案对我不起作用。我有一个小工具,它应该读取我想拥有的文件并将其打包为资源,并依赖于其他我希望将其作为jar而不是单个类的项目(我正在使用Eclipse Helios)。 作为Eclipse中的应用程序,我可以通过以下方式访问资源 当且仅当将资源文件夹放置在输出路径(已编译的源)下时,并且如果将其放置在src文件夹中时,则不是这样。 当我打

  • 我制作了一个简单的applet,它加载了包含在中的图像。我制作的jar文件。该项目有一个名为“kap12”的包和一个名为“U1”的类。我有一个名为“resrc”的文件夹,其中包含我的图像。此文件夹位于根目录中(与kap12文件夹相同)。 这是目录结构: 当我在Eclipse中使用Appletviewer(没有.jar)运行该程序时,它运行得很好。它定位并显示图像。但当我用html运行它时。然后程序

  • 问题内容: 我有全部传播异常的方法,然后在一个地方处理,但是我意识到了一些事情。 假设我有这样的方法 我的问题是,如果doSometing()方法引发异常,该语句将不会关闭,但我不想在那里处理异常。尝试并捕获只会抛出异常并最终关闭语句的正确方法吗? 问题答案:

  • 问题内容: 在清理一些代码时,FindBugs向我介绍了一些使用Connection,CallableStatement和ResultSet对象的JDBC代码。这是该代码的一个片段: FindBugs指出这些应该在finally块内。我开始重构我的代码来做到这一点,我开始想知道如何在finally块中处理代码。 Connection对象的CallableStatement的创建可能会引发异常,而我