Как получить результат первого выполнившегося Promise, запущенного через Promise.all()
Разбор вопроса «Как получить результат первого выполнившегося Promise, запущенного через Promise.all()» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Вопрос
Как получить результат первого выполнившегося Promise, запущенного через Promise.all()
Профессия
Frontend Developer
Что хочет услышать интервьюер
Интервьюер хочет убедиться, что кандидат понимает разницу между Promise.all() и Promise.race(), и может правильно использовать их для решения задач асинхронного программирования.
Ключевые тезисы
- Promise.all() ждет выполнения всех Promise в массиве и возвращает массив их результатов.
- Чтобы получить результат первого выполнившегося Promise, можно использовать Promise.race().
- Promise.race() возвращает результат первого Promise, который завершится (успешно или с ошибкой).
- Пример использования: Promise.race([promise1, promise2]).then(result => console.log(result));
Подробный ответ
Promise.all() ожидает выполнения всех переданных Promise и возвращает массив их результатов в том же порядке. Однако, если нужно получить результат первого выполнившегося Promise (независимо от того, успешно или с ошибкой), следует использовать Promise.race(). Этот метод принимает массив Promise и возвращает новый Promise, который разрешается или отклоняется с результатом первого завершившегося Promise в массиве.
Promise.race() полезен в сценариях, где важна скорость ответа, например, при работе с несколькими API-серверами, когда достаточно ответа от любого из них. Важно понимать, что остальные Promise продолжат выполняться, но их результаты будут проигнорированы.
Если требуется обработать только первый успешный результат (игнорируя ошибки), можно комбинировать Promise.race() с дополнительной обработкой. Например, можно преобразовать отклоненные Promise так, чтобы они не прерывали цепочку, или использовать Promise.any() (если доступен в среде выполнения), который ожидает хотя бы один успешный результат.
Практические примеры
Пример 1
Пример с API-запросами:
const api1 = fetch('https://api1.example.com/data');
const api2 = fetch('https://api2.example.com/data');
Promise.race([api1, api2])
.then(response => console.log('First response:', response))
.catch(error => console.error('First error:', error));Пример 2
Пример с таймаутом:
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 5000));
const dataPromise = fetch('https://api.example.com/data');
Promise.race([dataPromise, timeout])
.then(data => console.log(data))
.catch(err => console.error(err));Частые ошибки
- Использование Promise.all() вместо Promise.race() для получения первого результата
- Неучет того, что Promise.race() завершается при первом результате, даже если это ошибка
- Забывание обработки ошибок в Promise.race()
Связанные темы
- Promise.any() - ожидает первый успешный результат (ES2021)
- Promise.allSettled() - ожидает завершения всех Promise независимо от результата
- Async/await синтаксис для работы с Promise
Follow-up вопросы
В чем разница между Promise.all() и Promise.race()?
Уровень: basic
Promise.all() ждет выполнения всех Promise и возвращает массив их результатов, а Promise.race() возвращает результат первого выполнившегося Promise (успешно или с ошибкой).
Что произойдет, если один из Promise в Promise.race() завершится с ошибкой?
Уровень: intermediate
Promise.race() вернет ошибку первого Promise, который завершился с ошибкой. Остальные Promise будут проигнорированы, даже если они завершатся успешно.
Можно ли использовать Promise.race() для реализации таймаутов?
Уровень: intermediate
Да, можно создать Promise, который завершается с ошибкой через setTimeout, и передать его в Promise.race() вместе с основным Promise. Если основной Promise не выполнится за заданное время, сработает таймаут.
Как обработать ситуацию, когда нужно получить первый успешный результат, а не первый завершившийся (включая ошибки)?
Уровень: advanced
Можно обернуть Promise.race() в дополнительную логику, которая будет проверять результат на успешность и повторять запросы, пока не получит успешный ответ. Либо использовать библиотеки типа p-any.
Какие есть альтернативы Promise.race() для получения первого успешного результата?
Уровень: advanced
Можно использовать Promise.any() (если поддерживается), который возвращает первый успешный результат, или комбинировать несколько Promise с цепочками .then() и .catch().
Как обрабатывать Promise
Разбор вопроса «Как обрабатывать Promise» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Как применял finally в Promise на практике
Разбор вопроса «Как применял finally в Promise на практике» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.