Я являюсь частью небольшой команды, работающей на довольно небольшом веб-сайте с учетными записями пользователей; сейчас около 100 пользователей. И мы используем Amazon Cognito для управления пользователями. На нашем сайте есть сводная страница, которая отображает список / таблицу всех пользователей и различные атрибуты. Однако существует жесткое ограничение на количество элементов, возвращаемых вызовом API Amazon Cognito listUsers, в данном случае 60.
К счастью, вызов API также возвращает токен, который будет использоваться для выполнения последующих вызовов, если есть больше пользователей. Используя эти токены, мы можем запросить полный список всех пользователей.
Кроме того, наш веб-сайт использует реагирующий-редукс и библиотеку javascript bluebird. В контексте этого вопроса, компонент, запрашивающий список всех пользователей, также отправляет действия (кусок избыточности), и CognitoIdentityServiceProvider из aws-sdk Amazon передается bluebird Promise.promisfyAll (добавляет асинхронный постфикс к вызову listUser). Я изменяю этот компонент, чтобы получить полный список пользователей.
В качестве черновика запроса полного списка пользователей я использовал рекурсивную функцию для объединения обещаний, пока токен нумерации страниц, возвращаемый из Amazon, не будет неопределенным и сохранит результаты в некоторых переменных класса. Я использовал это сообщение на форуме в качестве ссылки.
Это работает, но я не очень доволен реализацией; в нашем случае все будет хорошо, поскольку у нас около 100 пользователей, но я не знаю, будет ли это хорошо масштабироваться до тысяч пользователей или более. Я понимаю, что рекурсия настолько опасна, что я не знаю, может ли эта техника вызвать проблемы, когда число обещаний / вызовов возрастает. Вопросы о накладных расходах и управлении памятью приходят на ум. Тем не менее, нам не нужно беспокоиться о количестве пользователей, стремительно растущих в тысячах, хотя бы некоторое время, но я все еще хочу узнать о потенциально предпочтительных и / или более безопасных методах достижения того же самого.
Следующие фрагменты взяты из компонента, запрашивающего список пользователей:
import Promise from 'bluebird';
import { CognitoIdentityServiceProvider } from './services/aws';
export const fetchRegisteredUsers = () => (dispatch) => {
...
let allUsersTemp = [];
let paginationToken;
const getUserList = () => {
let tempUserTest = CognitoIdentityServiceProvider.listUsersAsync({
UserPoolId: process.env.COGNITO_USER_POOL_ID,
PaginationToken: paginationToken
});
return tempUserTest.then((tempUser) => {
allUsersTemp = allUsersTemp.concat(tempUser.Users);
paginationToken = tempUser.PaginationToken;
if(paginationToken) {
return getUserList();
} else {
return;
}
})
}
const adminUsers = CognitoIdentityServiceProvider.listUsersInGroupAsync(adminParams);
return Promise.all([adminUsers]).then(
([{ Users: adminUsers }]) => {
getUserList().then((item) => {
let allUsers = allUsersTemp;
const adminUsernames = adminUsers.map(user => user.Username);
allUsers.forEach(user => {
let mappedAttributes = {};
user.Attributes.forEach(attribute => mappedAttributes[attribute.Name] = attribute.Value);
user.Attributes = mappedAttributes;
user.isAdmin = adminUsernames.includes(user.Username);
});
dispatch({
type: FETCH_REGISTERED_USERS_SUCCESS,
payload: allUsers
});
});
}, ...
Из того, что я понимаю, вызов bluebird Promise.all ждет, пока каждый переданный ему элемент не сможет разрешиться, прежде чем выполнить то, что находится в .then; до внесения каких-либо изменений в код было два списка: один для пользователей и один для администраторов. Promise.all дождался выполнения обоих обещаний, выполнил некоторую базовую обработку данных и возвратил данные в полезной нагрузке диспетчеризации действий.
После моих изменений логика для обработки и возврата списка пользователей выполняется после завершения рекурсивной цепочки обещаний (getUserList).
Мой вопрос: С этим методом все в порядке, и могу ли я использовать его как есть? Или это небезопасно, и если да, то в чем конкретно проблема? И есть ли лучший способ вообще?
Мои слабые места - рекурсия и обещания / bluebird, поэтому, пожалуйста, не стесняйтесь критиковать код на все, что связано с этими темами