> Каким методом промиса выполнить несколько параллельных запросов и получить результат каждого (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: SmartWay
Стек: JavaScript
> Пример ответа
Короткий ответ
Для параллельных запросов с получением всех результатов используйте Promise.all или Promise.allSettled. Promise.all завершится ошибкой при первом rejected промиса, а Promise.allSettled дождётся всех и вернёт массив объектов с полями status и value/reason. Если нужен первый успешный результат - Promise.any, первый завершённый - Promise.race.
Подробное объяснение
Promise.all принимает итерируемый объект промисов и возвращает новый промис, который разрешается массивом результатов в том же порядке, что и входные промисы. Если любой из промисов отклоняется, Promise.all немедленно отклоняется с этой ошибкой - остальные результаты теряются. Это подходит, когда все запросы критически важны.
Promise.allSettled (ES2020) ждёт завершения всех промисов независимо от их статуса. Результат - массив объектов {status: "fulfilled", value: ...} или {status: "rejected", reason: ...}. Идеально для сценариев, где нужно обработать каждый ответ индивидуально, например, при загрузке данных из нескольких независимых источников.
Promise.race возвращает первый завершённый промис (любой статус). Promise.any (ES2021) - первый успешный, отклоняет только если все промисы отклонены.
На практике
Для параллельных HTTP-запросов в браузере используйте fetch с Promise.all или Promise.allSettled. Учитывайте лимиты браузера на одновременные соединения (обычно 6 на домен) - при большом количестве запросов применяйте throttling или пакетную обработку. Для отмены запросов используйте AbortController в паре с Promise.race.
Пример кода
JAVASCRIPT// Параллельные запросы с Promise.allasync function fetchAllUsers(userIds) {try {const results = await Promise.all(userIds.map(id => fetch(`/api/users/${id}`).then(res => res.json())));return results; // массив данных в порядке userIds} catch (error) {console.error('Один из запросов упал:', error);throw error;}}// Promise.allSettled - обрабатываем каждый ответ отдельноasync function fetchWithFallback(urls) {const results = await Promise.allSettled(urls.map(url => fetch(url).then(r => r.json())));const successful = results.filter(r => r.status === 'fulfilled').map(r => r.value);const failed = results.filter(r => r.status === 'rejected').map(r => r.reason);return { successful, failed };}
Как отвечать на собеседовании
Начните с прямого ответа - Promise.all и Promise.allSettled. Кратко объясните разницу: all для критичных запросов, allSettled когда нужно собрать все результаты. Упомяните Promise.race и Promise.any как альтернативы. Приведите пример с fetch и обработкой ошибок. Если спросят про производительность, скажите о лимите соединений и throttling. Не углубляйтесь в детали реализации V8 или event loop, если не спросят.
Что проверяет интервьюер
- Понимание асинхронности и промисов на уровне выше базового
- Умение выбирать правильный метод под задачу (все результаты vs первый успешный)
- Знание современных возможностей (allSettled, any)
- Практический опыт с обработкой ошибок в параллельных запросах
- Понимание trade-off между
allиallSettled
Типичные ошибки
- Использовать
Promise.allкогда нужны все результаты, включая ошибки - лучшеallSettled - Забывать, что
Promise.allотклоняется при первой же ошибке, теряя остальные результаты - Не обрабатывать reject внутри map, из-за чего
Promise.allпадает целиком - Путать
Promise.raceиPromise.any- первый берёт любой завершённый, второй только успешный - Игнорировать лимиты браузера на параллельные соединения при массовых запросах
> Похожие задачи по frontend
Являются ли функции объектами в JavaScript?
Можно ли работать с куки на фронтенде через JavaScript
Как работает Redux Saga
Как работают редьюсеры в Redux
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью