Что такое Promise.race
Разбор вопроса «Что такое Promise.race» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Вопрос
Что такое Promise.race
Профессия
Frontend Developer
Что хочет услышать интервьюер
Интервьюер хочет убедиться, что кандидат понимает назначение Promise.race, его поведение и практическое применение. Также важно, чтобы кандидат мог объяснить, как этот метод отличается от других методов работы с промисами, таких как Promise.all.
Ключевые тезисы
- Promise.race — это метод, который принимает массив промисов и возвращает новый промис.
- Этот новый промис завершается (resolved или rejected) как только завершается первый промис из переданного массива.
- Результат Promise.race — это результат первого завершенного промиса, независимо от его статуса (успех или ошибка).
- Пример использования: контроль времени выполнения асинхронных операций или реализация тайм-аутов.
Подробный ответ
Promise.race — это метод, который принимает массив промисов и возвращает новый промис. Этот новый промис завершается (resolved или rejected) как только завершается первый промис из переданного массива. Результат Promise.race — это результат первого завершенного промиса, независимо от его статуса (успех или ошибка). Это полезно в сценариях, где важно получить результат самого быстрого промиса, например, при реализации тайм-аутов или выборе между несколькими источниками данных.
Promise.race не ждет завершения всех промисов, в отличие от Promise.all. Если первый промис завершается с ошибкой, Promise.race немедленно отклоняется с этой ошибкой. Если первый промис завершается успешно, Promise.race разрешается с его значением. Это делает его идеальным для контроля времени выполнения операций.
Важно отметить, что Promise.race не отменяет остальные промисы — они продолжают выполняться в фоне, но их результаты игнорируются. Это может привести к утечкам ресурсов, если не учитывать этот аспект.
Пример использования: если у вас есть запрос к API и вы хотите ограничить время его выполнения, можно использовать Promise.race для создания тайм-аута. Если API не отвечает в течение заданного времени, промис тайм-аута завершится первым, и вы сможете обработать эту ситуацию.
Практические примеры
Пример 1
Пример с тайм-аутом запроса:
const fetchWithTimeout = (url, timeout) => {
const fetchPromise = fetch(url);
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Request timeout')), timeout);
});
return Promise.race([fetchPromise, timeoutPromise]);
};// Использование: fetchWithTimeout('https://api.example.com/data', 5000)
.then(response => console.log(response))
.catch(error => console.error(error));Пример 2
Пример выбора между несколькими источниками данных:
const source1 = fetch('https://source1.example.com/data');
const source2 = fetch('https://source2.example.com/data');
Promise.race([source1, source2])
.then(data => console.log('First response:', data))
.catch(error => console.error('First error:', error));Частые ошибки
- Забывают, что Promise.race не отменяет остальные промисы, что может привести к утечкам ресурсов
- Путают Promise.race с Promise.all или Promise.any, ожидая другого поведения
- Не обрабатывают случай, когда первый завершенный промис отклонен (rejected)
Связанные темы
- Promise.all — ждет завершения всех промисов или первого отклоненного
- Promise.any — завершается при первом успешном промисе (из ES2021)
- Promise.allSettled — ждет завершения всех промисов независимо от их статуса
- Async/await — современный синтаксис для работы с промисами
Follow-up вопросы
Как можно использовать Promise.race для реализации тайм-аута запроса?
Уровень: intermediate
Promise.race можно использовать, передав массив из исходного промиса запроса и промиса, который отклоняется через setTimeout. Если запрос не завершится до тайм-аута, Promise.race вернет отклоненный промис с ошибкой тайм-аута.
Что произойдет, если передать пустой массив в Promise.race?
Уровень: basic
Promise.race с пустым массивом вернет промис, который никогда не разрешится, так как нет ни одного промиса для соревнования.
Чем отличается поведение Promise.race от Promise.any?
Уровень: intermediate
Promise.race завершается с результатом первого завершенного промиса (независимо от успеха или ошибки), а Promise.any ждет первого успешно выполненного промиса, игнорируя отклонения, пока есть хотя бы один unresolved промис.
Как обработать ошибку в Promise.race, если первый завершенный промис отклонен?
Уровень: basic
Нужно использовать .catch() или try/catch в async/await. Ошибка будет содержать причину отклонения первого промиса, и ее можно обработать соответствующим образом.
Можно ли использовать Promise.race для отмены асинхронных операций? Какие есть ограничения?
Уровень: advanced
Promise.race не отменяет операции — остальные промисы продолжают выполняться. Для настоящей отмены нужно использовать AbortController или аналогичные механизмы, особенно для fetch-запросов.
Что такое Macrotask
Разбор вопроса «Что такое Macrotask» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
Какие знаешь статические методы Promise
Разбор вопроса «Какие знаешь статические методы Promise» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.