在列出aws认知用户时,我的node js应用程序遇到问题。
仅当我拥有60多个Cognito用户时,才会出现此问题。
下面是我的代码段。
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);
}
有帮助吗?
请让我知道是否需要其他任何东西。
答案 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链接在一起。一旦代码到达递归末尾,那么链中的每个承诺都将得到解决。此实现使用的是纯承诺,因此很容易理解。