> Каким методом промиса выполнить несколько параллельных запросов и получить результат каждого (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Aston
Стек: JavaScript
> Пример ответа
Короткий ответ
Для параллельных запросов с получением каждого результата используйте Promise.allSettled(). В отличие от Promise.all(), он не прерывается при ошибке и возвращает массив объектов с полями status ("fulfilled" или "rejected") и value или reason. Для простых случаев, когда нужны все успешные результаты, подойдёт Promise.all() с блоком catch.
Подробное объяснение
Основные методы для параллельного выполнения промисов:
-
Promise.all()- принимает массив промисов, возвращает массив результатов в том же порядке. Если хотя бы один промис отклонён, весь метод сразу переходит вrejectedс ошибкой первого отклонённого промиса. Подходит, когда критичен успех всех запросов. -
Promise.allSettled()- ждёт завершения всех промисов независимо от результата. Возвращает массив объектов с{status: "fulfilled", value: ...}или{status: "rejected", reason: ...}. Идеален, когда нужно получить каждый результат, включая ошибки. -
Promise.race()- возвращает результат первого завершённого промиса (успех или ошибку). Используется для таймаутов. -
Promise.any()- возвращает первый успешный результат. Если все промисы отклонены, переходит вrejectedсAggregateError.
Для параллельного выполнения сами запросы должны быть запущены одновременно (не через await последовательно), а массив промисов передан в один из методов.
На практике
В реальных приложениях выбор метода зависит от бизнес-логики:
- Загрузка данных для dashboard:
Promise.allSettled()- даже если один сервис упал, остальные данные показываем. - Критическая последовательность операций (например, оплата + списание):
Promise.all()- если что-то пошло не так, откатываем всё. - Загрузка изображений для галереи:
Promise.allSettled()- показываем те, что загрузились. - Поиск по нескольким источникам:
Promise.any()- берём первый ответ.
Важно помнить про обработку ошибок: для Promise.all() используйте catch на уровне всего вызова, для Promise.allSettled() - фильтруйте результаты по status.
Пример кода
JAVASCRIPT// Параллельные запросы с получением каждого результатаconst urls = ['/api/users', '/api/posts', '/api/comments'];const requests = urls.map(url => fetch(url).then(res => res.json()));// Вариант 1: Promise.allSettled() - получаем все результатыPromise.allSettled(requests).then(results => {results.forEach((result, index) => {if (result.status === 'fulfilled') {console.log(`Успех для ${urls[index]}:`, result.value);} else {console.error(`Ошибка для ${urls[index]}:`, result.reason);}});});// Вариант 2: Promise.all() - если нужны только успешные, но важен порядокPromise.all(requests).then(([users, posts, comments]) => {console.log('Все данные получены:', { users, posts, comments });}).catch(error => {console.error('Один из запросов упал:', error);});
Как отвечать на собеседовании
Начните с прямого ответа - Promise.allSettled(). Объясните разницу между методами и когда какой применять. Приведите пример из реальной практики, где вы выбирали между all и allSettled. Упомяните, что для truly parallel execution сами промисы должны быть созданы до вызова метода (не через await в цикле). Покажите понимание обработки ошибок в каждом случае. Если спросят про производительность - скажите, что все методы запускают промисы конкурентно, разница только в обработке результатов.
Что проверяет интервьюер
- Понимание асинхронности JavaScript и event loop
- Знание статических методов Promise и их trade-off
- Умение выбирать правильный инструмент под задачу
- Навыки обработки ошибок в параллельных операциях
- Понимание разницы между конкурентным и параллельным выполнением в однопоточном JS
Типичные ошибки
- Использование
Promise.all()когда нужны все результаты, включая ошибки - приводит к потере данных при первом же reject - Запуск запросов последовательно через
awaitв циклеfor...ofвместо параллельного запуска - Игнорирование обработки ошибок для
Promise.all()- отсутствиеcatchприводит к необработанным rejections - Путаница между
Promise.allSettled()иPromise.all()в контексте "получить результат каждого" - Неправильная интерпретация порядка результатов - все методы возвращают результаты в том же порядке, что и входной массив
> Похожие задачи по frontend
Как распределялось время между фронтендом и бэкендом в работе
Как создать промис, который возвращает результат первого успешно завершившегося промиса в JavaScript
Какой опыт есть с особенностями браузеров
Что такое замыкания в JavaScript и для чего они нужны
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью