【问题标题】:Call function after two promises resolve in angularJS, one using result from other在 angularJS 中解决两个承诺后调用函数,一个使用来自另一个的结果
【发布时间】:2017-03-10 14:22:44
【问题描述】:

在一个控制器函数中,我做了一些操作:

  • 获取有承诺的组织列表
  • 在此承诺之后,我循环遍历它们中的每一个以提取一些数据并填充我的一些控制器属性。
  • 其中一个操作是调用另一个 Promise 来收集附属于该组织的所有用户,其中包含一个循环来提取名称和其他内容。
  • 当我得到所有这些信息时,每个组织都已被解析,其中的所有用户也是如此,我必须调用一个函数来更新我的视图。

我通过设置一些标志(orgParsedusersParsed)让它工作,但我发现它是......代码耻辱。

我听说有一种方法可能是通过使用$q 来等待两个promise 以及它们的“then”中的循环在调用我的视图函数之前解决。但我很难应用此代码更改,因为第二个承诺使用第一个承诺的结果来收集组织 ID。

这是我当前的代码:

this.getOrgData = function () {
    return Service.getList().then(function (result) {
        var orgCount = result.Objects.length;
        var orgParsed = 0;

        _.forEach(result.Objects, function (org) {  
            org.Users = [];

            // Some logic here using 'org' data

            Service.getUsers(org.Id, 0, 0).then(function (userResult) {                        
                usersParsed = 0;

                _.forEach(userResult.Objects, function (user) {
                    // Some Logic here using 'user.Name'            
                    usersParsed++;                         
                });
                orgParsed++;

                if (orgParsed === orgCount && usersParsed === userResult.Objects.length) {
                    self.sortMenuList(); // My view Function
                }
            });
        });
        $scope.$broadcast("getOrgData");
    });
};

只有当我可以确定每个公司的所有用户都以更优雅/高效/安全的方式解析时,您是否看到任何触发我的 self.sortMenuList() 函数的方法?

【问题讨论】:

  • 您需要usersParsed 做什么? doneUsers 是什么?
  • $q.all() 是等待多个端点调用结果的角度方式
  • doneUsers 是一个错误。问题已更正。

标签: javascript angularjs promise


【解决方案1】:

是的,绝对应该用$q.all 代替计数,尤其是因为您没有费心处理任何错误。

this.getOrgData = function () {
    return Service.getList().then(function (result) {
        $scope.$broadcast("getOrgData"); // not sure whether you want that here before the results from the loop
        return $q.all(_.map(result.Objects, function (org) {  
            org.Users = [];
            // Some logic here using 'org' data
            return Service.getUsers(org.Id, 0, 0).then(function (userResult) {
                _.forEach(userResult.Objects, function (user) {
                    // Some Logic here using 'user.Name' 
                });
            });
        }));
    }).then(function() {
       self.sortMenuList(); // My view Function;
    })
};

【讨论】:

    【解决方案2】:

    你描述的问题听起来像是你想等到一定数量的承诺都解决了,然后对结果做一些事情。当您使用Promise.all() 时,这真的很容易:

    this.getOrgData = function () {
        return Service.getList().then(function (result) {
            var promises = [];
    
            _.forEach(result.Objects, function (org) {  
                org.Users = [];
    
                // Some logic here using 'org' data
    
                // Store the promise for this user in the promises array
                promises.push(Service.getUsers(org.Id, 0, 0));
            });
    
    
            // userResults is an array of all the results of the promises, in the same order as the getUsers was called
            Promise.all(promises).then(function (userResults) {
                _.forEach(userResults, function(userResult) {                        
                    _.forEach(userResult.Objects, function (user) {
                        // Some Logic here using 'user.Name'            
                    });
                });
    
                self.sortMenuList();
            });
    
            $scope.$broadcast("getOrgData");
        });
    };
    

    【讨论】:

    • 谢谢,非常有用,但我会选择$q.all
    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    相关资源
    最近更新 更多