> Почему Promise.race не подходит для выбора лучшего покупателя в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
Promise.race не подходит для выбора лучшего покупателя, потому что он реагирует на первый завершившийся промис, а не на лучший результат. В контексте покупателей это означало бы выбор того, кто быстрее ответил, а не того, кто предложил лучшую цену или условия. Для выбора лучшего покупателя нужна агрегация всех результатов и сравнение по критериям, а не гонка за скоростью.
Подробное объяснение
Promise.race предназначен для сценариев, где важна скорость завершения: например, таймауты, отмена устаревших запросов или выбор первого доступного источника данных. Его семантика - "первый resolved или rejected", и он не учитывает содержимое результатов.
Выбор лучшего покупателя - это задача оптимизации по метрике (цена, сроки, надёжность). Здесь нужно:
- дождаться всех предложений (Promise.all или Promise.allSettled),
- сравнить их по заданным критериям,
- выбрать оптимальный вариант.
Использование Promise.race приведёт к систематической ошибке: покупатель с самым быстрым ответом почти всегда будет выбран, даже если его условия хуже. Это особенно критично, если ответы приходят с разной задержкой - например, крупные компании отвечают медленнее, но предлагают лучшие условия.
Кроме того, Promise.race не обрабатывает частичные отказы: если первый промис rejected, гонка завершится ошибкой, хотя другие покупатели могли дать валидные предложения. Для надёжного выбора нужен allSettled с последующей фильтрацией успешных результатов.
На практике
В реальном коде выбор лучшего покупателя обычно реализуется так:
- отправляются параллельные запросы ко всем потенциальным покупателям,
- ожидается завершение всех (с таймаутом на каждый запрос отдельно),
- результаты сортируются по цене или другому критерию,
- выбирается первый из отсортированного списка.
Таймауты при этом накладываются на каждый запрос индивидуально (через Promise.race с задержкой), но не на всю группу. Это позволяет отсечь "молчунов", не теряя при этом медленных, но выгодных предложений.
Пример кода
JAVASCRIPT// Неправильно: race выберет самого быстрого, а не лучшегоconst wrongChoice = await Promise.race(buyers.map(buyer => buyer.getOffer()));// Правильно: ждём всех, фильтруем ошибки, сортируем по ценеconst results = await Promise.allSettled(buyers.map(buyer => buyer.getOffer().then(offer => ({ buyer, offer }))));const validOffers = results.filter(r => r.status === 'fulfilled').map(r => r.value);// Сортируем по возрастанию ценыvalidOffers.sort((a, b) => a.offer.price - b.offer.price);const bestBuyer = validOffers[0];
Как отвечать на собеседовании
Начните с чёткого разграничения: race - про скорость, выбор лучшего - про качество. Приведите пример, где скорость ответа не коррелирует с выгодностью. Упомяните, что race полезен для таймаутов, но не для агрегации. Покажите, как правильно: allSettled + сортировка. Если спросят про производительность - скажите, что все запросы всё равно выполняются параллельно, разница только в обработке результатов.
Что проверяет интервьюер
- Понимание семантики Promise.race и его отличий от Promise.all/allSettled.
- Умение выбирать правильный инструмент под задачу, а не применять первый попавшийся.
- Осознание trade-off между скоростью и качеством в асинхронных сценариях.
- Навык обработки частичных ошибок при параллельных запросах.
Типичные ошибки
- Утверждение, что race можно использовать, если "покупатели отвечают примерно одинаково" - это не гарантия, а допущение.
- Игнорирование rejected промисов: race упадёт при первой ошибке, даже если остальные ответили успешно.
- Попытка "подкрутить" race через обёртки с задержками - это усложнение без выгоды, проще использовать allSettled.
- Смешение понятий: "первый" и "лучший" - разные критерии, и race оптимизирует только первый.
> Похожие задачи по frontend
Как различать и отличать action в Redux?
Как работает массив tickets в JavaScript
Как написать полифил для метода map в JavaScript
Как исправить проблему с var в цикле с setTimeout в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью