Приложение Node JS зависает при разрешении () - PullRequest
0 голосов
/ 03 июля 2018

Я столкнулся с проблемой в моем приложении js для узла при выводе списка пользователей aws cognito.

Эта проблема возникает только тогда, когда у меня более 60 пользователей Cognito.

Справочник по 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 мы можем читать только 60 пользователей одновременно, в этом случае я отправляю paginationtoken в парам.

Мой код застревает на линии resolve().

Если я уберу фрагмент кода ниже, он будет работать.

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

Любая помощь?

Пожалуйста, дайте мне знать, если что-нибудь понадобится.

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Можете ли вы попробовать следующий код:

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

Я сделал небольшие улучшения в исходном коде, исходный код дает много обещаний, которые будут зависать в состоянии ожидания, поскольку ожидание при окончательном обещании конечного условия рекурсии никогда не разрешается. Я использую цепочку неявных обещаний, возвращая обещание в блоке обещаний, поэтому все обещания объединяются. Как только код достигнут конца рекурсии, каждое обещание в цепочке будет выполнено. Эта реализация использует чистые обещания, поэтому ее легко понять.

0 голосов
/ 03 июля 2018

В случае, если упомянутое утверждение if истинно, вы выполняете рекурсию своей функции: isAllowedToDeleteOrRevokeUsers(…).

Не следует делать рекурсивные вызовы внутри обещания, но разрешать обещание для каждой страницы и повторно выполнять его для каждой новой страницы нумерации страниц.

Другими словами: убедитесь, что каждый путь в логике внутри обещания приводит к вызову resolve() или reject(). Если логика вашего приложения требует рекурсии, реструктурируйте эту функцию, чтобы в каждой рекурсии создавалось и обрабатывалось новое обещание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...