Я пытаюсь найти эффективный способ запуска серии пакетных сетевых запросов к API.API принимает массив идентификаторов и возвращает документ JSON для каждого из предоставленных идентификаторов, если он доступен в базе данных.Для небольшого количества идентификаторов, таких как 10 или 25, операция выполняется довольно быстро.Тем не менее, у меня есть 25 000+ (и растущих) идентификаторов, которые необходимо сделать при первом вызове.
Сначала я попытался разделить эти запросы на ~ 5000 идентификаторов в массиве, а затем с помощью Promise.all
дождался возвращения всех запросов перед объединением данных.Это сократило время получения всех документов с 2 минут до 15 секунд (к счастью, это балансировка нагрузки).Все началось хорошо, но я знаю, что по мере роста приложения будет намного больше документов.Я попытался уменьшить размер, который я начал, до размера 1000, но это достигло предела стека и кучи.
Есть ли для меня более эффективный способ решить эту проблему только с помощью JavaScript?В конце концов, это приложение может легко увеличить необходимые документы с 25K до 50K за неделю, и слои кэширования, такие как Redis, в настоящее время недоступны.
Вот некоторый псевдокод того, как выглядит мой пакетный запрос:
const httpRequest = async arr => {
return await axios.post(url, {
keys: JSON.stringify(arr)
});
}
// ids is an array of 25000+ strings
const batchRequest = async (ids) => {
const batch = [];
// Leave array ids from source immutable, clone it
const cloneSource = Array.from(ids);
let lengthOfIds = ids.length;
while (cloneSource.length > 0) {
// Break off the ids into separate arrays
const sliced = cloneSource.slice(lengthOfIds - 1000, lengthOfIds);
batch.push(sliced);
// Reduce length, to make sure there are no duplicates
lengthOfIds -= 1001;
if (cloneSource.length === 1) {
batch.push(cloneSource.splice(0, 1))
break;
}
}
const mapFetches = await Promise.all(httpRequest);
return [
mapFetches.reduce((acc, curr) => [...acc, ...curr.data], [])
];
}