首页 文章

如何在复杂的资源加载序列中正确链接promise?

提问于
浏览
0

在角度代码中,我有一个像这样的链式承诺:

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

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

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!');
                });
        };

我打算在控制器初始化的代码中使用,如下所示:

// 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 
            });

但是,这并不像我想的那样有效 . 所有承诺解决后,理想情况下,“我会在所有承诺解决后在这里做点什么”的消息必须出现 . 相反,我可以看到它比在列出的函数中已解析的promises的消息更早出现了ensureTypeLoaded .

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

  • 它返回一个在解决所有链式加载时解析的promise;

  • 如果"internal" promise中的任何一个失败,则该函数不应继续进行下一次调用,而是返回被拒绝的promise .

  • 显然,如果我调用ensureTypesLoaded() . then(...),那么在解决了EnsureTypesLoaded中的所有内容后,必须调用then()中的内容 .

请帮助我正确 Build 链式承诺 .

1 回答

  • 1

    我认为问题出在你的loadProjectList函数中 . 因为.then()应该接收在结果时调用的函数 . 通常是功能返回链承诺 .

    但在您的情况下,您可以立即并行调用所有负载 . 美元范围传递并不复杂 . 但我认为你的代码应该是这样的

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

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

相关问题