В чем разница между Promise.all, Promise.any и Promise.race в JavaScript
Что проверяют
Знаете ли вы поведение всех трёх, включая случай отказа, и помните ли про allSettled.
Как отвечать
Promise.all: ждёт все промисы. При успехе возвращает массив результатов в порядке аргументов, а не в порядке завершения. При первом же отказе немедленно отклоняется этой ошибкой, остальные результаты теряются;Promise.allSettled: тоже ждёт все, но никогда не отклоняется. Возвращает массив объектов со статусомfulfilledилиrejected;Promise.any: возвращает первый успешный. Отказы игнорирует, пока есть надежда. Если отклонились все, отклоняется сAggregateError, где в полеerrorsлежат все ошибки;Promise.race: возвращает первый завершившийся любым способом. Победил отказ, значит результат это отказ.
Разница между any и race в этом и состоит: any ждёт успеха, race ждёт события.
Когда что:
allдля параллельной загрузки данных, каждый из которых обязателен: без любого куска страница всё равно не отрисуется;allSettledкогда допустим частичный успех: три виджета на панели, один не загрузился, остальные показываем;anyдля запроса к нескольким равнозначным источникам: берём то, что ответило первым и успешно;raceдля ограничения времени: гонка полезного промиса с таймером, отклоняющимся через N миллисекунд.
Важная общая деталь: проигравшие промисы не отменяются. Они продолжают выполняться, их запросы уходят на сервер, а результат просто игнорируется. Для настоящей отмены нужен AbortController, иначе таймаут через race создаёт видимость отмены, а нагрузка остаётся.
И вторая: все четыре метода запускают промисы не сами. Промис начинает выполняться в момент создания, поэтому передавать в них надо уже созданные промисы, а не функции.
Где спотыкаются
Ждут, что all вернёт результаты в порядке завершения.
Используют all там, где нужен allSettled, и теряют всё из-за одного отказа.
Путают any и race.
Считают, что race отменяет проигравший запрос.