两个promises在angularJS中解析后调用函数,一个使用其他结果

时间:2017-03-10 14:22:44

标签: javascript angularjs promise

在控制器功能中,我做了一些操作:

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

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

我听说过一种方法可能是通过使用$q来等待两个promises,并且可能在调用我的view函数之前解析其“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()函数的方法?

2 个答案:

答案 0 :(得分:2)

是的,计数肯定会被$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;
    })
};

答案 1 :(得分:1)

您描述的问题听起来像是要等到一定数量的承诺全部解决,然后对结果做一些事情。使用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");
    });
};