> Как обработать успешное разрешение одного из промисов в функции any? (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Яндекс

Стек: JavaScript

> Пример ответа

Короткий ответ

Для обработки успешного разрешения одного из промисов в Promise.any используется метод .then() или async/await. Promise.any возвращает первый успешно resolved промис, игнорируя reject. Если все промисы отклонены, возвращается AggregateError. Результат обрабатывается стандартным способом через цепочку промисов или синтаксис try/catch с await.

Подробное объяснение

Promise.any принимает итерируемую коллекцию промисов и возвращает новый промис, который разрешается значением первого успешно выполненного промиса. Если все промисы отклонены, возвращается AggregateError со списком всех ошибок. Это отличается от Promise.race, который реагирует на первый завершённый промис (независимо от результата). Promise.any полезен, когда нужно получить первый успешный результат из нескольких параллельных операций, например, при запросах к разным CDN или API-эндпоинтам.

На практике

В реальных проектах Promise.any часто применяется для fallback-запросов, когда мы пытаемся получить данные из нескольких источников и используем первый успешный ответ. Важно помнить, что если все промисы отклонены, нужно обработать AggregateError - это нестандартная ошибка, которую не все инструменты корректно сериализуют. Для отлова всех ошибок используйте errors свойство AggregateError.

Пример кода

JAVASCRIPT
const fetchFromCDN1 = fetch('https://cdn1.example.com/data');
const fetchFromCDN2 = fetch('https://cdn2.example.com/data');
const fetchFromCDN3 = fetch('https://cdn3.example.com/data');
Promise.any([fetchFromCDN1, fetchFromCDN2, fetchFromCDN3])
.then(response => {
console.log('Получен ответ от:', response.url);
return response.json();
})
.then(data => {
console.log('Данные:', data);
})
.catch(error => {
if (error instanceof AggregateError) {
console.error('Все запросы провалились:', error.errors);
} else {
console.error('Неожиданная ошибка:', error);
}
});
// Асинхронный вариант
async function getFirstSuccessfulData() {
try {
const response = await Promise.any([fetchFromCDN1, fetchFromCDN2, fetchFromCDN3]);
return await response.json();
} catch (error) {
if (error instanceof AggregateError) {
throw new Error('Все источники недоступны');
}
throw error;
}
}

Как отвечать на собеседовании

Начните с краткого определения Promise.any и его отличия от Promise.race. Покажите понимание обработки успешного случая через .then() и async/await. Упомяните AggregateError для случая, когда все промисы отклонены. Приведите практический пример использования, например, для fallback-запросов. Избегайте путаницы с Promise.all и Promise.allSettled. Будьте готовы обсудить, когда Promise.any предпочтительнее других комбинаторов.

Что проверяет интервьюер

Интервьюер оценивает знание современных методов работы с промисами, понимание различий между Promise.any, Promise.race, Promise.all и Promise.allSettled. Важно показать, что вы знаете про AggregateError и умеете его обрабатывать. Также проверяется способность применять Promise.any в реальных сценариях, а не только в теории.

Типичные ошибки

Путаница с Promise.race - кандидаты часто думают, что Promise.any тоже реагирует на первый завершённый промис. Игнорирование AggregateError - многие забывают, что при всех reject'ах выбрасывается специальная ошибка, а не обычный Error. Неправильная обработка ошибок - попытка поймать AggregateError как обычную ошибку без проверки instanceof. Использование Promise.any с одним промисом - в этом случае он ведёт себя как обычный промис, что может быть неочевидно.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью