Node JS应用程序卡在resolve()

时间:2018-07-03 09:35:44

标签: javascript node.js amazon-cognito

在列出aws认知用户时,我的node js应用程序遇到问题。

仅当我拥有60多个Cognito用户时,才会出现此问题。

Reference of API

下面是我的代码段。

function isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList) {
return new Promise(function(resolve, reject) {
  cognitoidentityserviceprovider.listUsers(params, function(err, data) {
       if (err) {
           logger.log("ERROR", "Error while calling listUsers API : " + err);
           reject({ code: 404, msg : err.message});
       } else {
           data.Users.forEach(function(user) {
               if (isUserASystemAdmin(user)) {
                   adminUserList.users.push(user);
               }
           });
           if (data.PaginationToken != undefined) {
                params.PaginationToken = data.PaginationToken;
                isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
           } else {
                // We've reached the end
                let totalCognitoAdminUsers = 0;
                let totalCognitoAdminUsersToDelete = 0;  

                adminUserList.users.forEach(function(adminUser) {
                    if (isCognitoUser(adminUser)) {
                        totalCognitoAdminUsers++;
                        if (listUsers.indexOf(adminUser.Username) > -1) {
                           totalCognitoAdminUsersToDelete++;
                        }
                    }
                });

               if(totalCognitoAdminUsers != 0 && (totalCognitoAdminUsers == totalCognitoAdminUsersToDelete)) {
                   reject({ code: 404, msg : "Cannot alter last Admin User controlled by standard authentication"});
               } else {
                   console.log("Return Success");
                   resolve();
               }
           }
       }
    });
  });
};

当我的用户少于60个时,此功能可以正常使用,但是根据AWS Docs,我们一次只能读取60个用户,在这种情况下,我在 paginationtoken 中发送了参数。

我的代码在resolve()行时卡住了。

如果我删除下面的代码,它将起作用。

 if (data.PaginationToken != undefined) {
    params.PaginationToken = data.PaginationToken;                    
    isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
 } 

有帮助吗?

请让我知道是否需要其他任何东西。

2 个答案:

答案 0 :(得分:2)

在提到的if语句为真的情况下,您将使用函数isAllowedToDeleteOrRevokeUsers(…)的递归。

您不应在promise中进行递归调用,而应解析每个页面的promise,并为分页的每个新页面重新执行它。

换句话说:确保promise中的逻辑中的每个路径都导致一个resolve()reject()调用。如果您的应用程序逻辑需要递归,请重新构造该函数,然后在每次递归时创建并解决一个新的Promise。

答案 1 :(得分:0)

您可以尝试以下代码吗?

function isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList) {
    return cognitoidentityserviceprovider.listUsers(params).promise().then((data) => {
        data.Users.forEach(function(user) {
            if (isUserASystemAdmin(user)) {
                adminUserList.users.push(user);
            }
        });
        if (data.PaginationToken != undefined) {
            params.PaginationToken = data.PaginationToken;
            return isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
       } else {
            // We've reached the end
            let totalCognitoAdminUsers = 0;
            let totalCognitoAdminUsersToDelete = 0;  

            adminUserList.users.forEach(function(adminUser) {
                if (isCognitoUser(adminUser)) {
                    totalCognitoAdminUsers++;
                    if (listUsers.indexOf(adminUser.Username) > -1) {
                       totalCognitoAdminUsersToDelete++;
                    }
                }
            });
            if(totalCognitoAdminUsers != 0 && (totalCognitoAdminUsers == totalCognitoAdminUsersToDelete)) {
                throw new Error({ code: 404, msg : "Cannot alter last Admin User controlled by standard authentication"});
            }
            console.log("Return success");
            return;
       }
    }).catch((err) => {
        logger.log("ERROR", "Error while calling listUsers API : " + err);
        throw new Error({ code: 404, msg : err.message});
    })
}

我对原始代码做了一些细微的改进,原始代码做出了很多承诺,这些承诺会像在最终递归结束条件中所期望的那样从未解决过,因此会停留在挂起状态。我通过在promise的prom中返回promise来使用隐式promise链,这使所有promise链接在一起。一旦代码到达递归末尾,那么链中的每个承诺都将得到解决。此实现使用的是纯承诺,因此很容易理解。