← Назад к вопросам

Что произойдет, если хотя бы один из запросов выполнит reject, что будет с остальными Promise?

1.3 Junior🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Влияние reject на "остальные" Promise в различных сценариях

Ответ на этот вопрос зависит от того, в каком контексте выполняются Promise. Понятие "остальные Promise" подразумевает, что мы говорим о нескольких параллельно запущенных асинхронных операциях. Поведение системы при отклонении одного из них определяется используемым методом для групповой обработки.

1. При использовании Promise.all()"fail-fast" стратегия

Promise.all() немедленно завершается с отклонением (rejection), как только любой из переданных Promise отклоняется. Остальные Promise продолжают своё выполнение "в фоне", но их результаты уже не могут быть получены через Promise.all().

const p1 = Promise.resolve('Первый успешен');
const p2 = new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Второй провалился')), 100)
);
const p3 = new Promise(resolve => 
    setTimeout(() => resolve('Третий успешен'), 200)
);

Promise.all([p1, p2, p3])
    .then(values => console.log(values))
    .catch(error => console.error('Ошибка в all:', error.message));
// Вывод: "Ошибка в all: Второй провалился"

// p3 всё равно выполнится, но его результат будет проигнорирован.
// Это может привести к "утечкам" (memory leaks), если операции имеют сайд-эффекты.

2. При использовании Promise.allSettled()"всегда успешен"

Promise.allSettled() ждёт завершения всех Promise, независимо от их статуса. Результатом будет массив объектов с информацией о каждом Promise: {status: 'fulfilled', value} или {status: 'rejected', reason}.

const promises = [
    Promise.resolve('Успех 1'),
    Promise.reject(new Error('Провал 2')),
    Promise.resolve('Успех 3')
];

Promise.allSettled(promises)
    .then(results => {
        results.forEach(result => console.log(result.status));
        // Вывод: "fulfilled", "rejected", "fulfilled"
    });
// Все Promise будут выполнены, reject одного не прерывает общий процесс.

3. При использовании Promise.any()"первый успешный"

Promise.any() ожидает, пока хотя бы один Promise успешно завершится. Если все Promise отклонятся, возвращается агрегированная ошибка AggregateError. Reject одного или нескольких Promise на поведение не влияет, пока есть шанс на успех.

const slowSuccess = new Promise(resolve => 
    setTimeout(() => resolve('Медленный успех'), 300)
);
const fastReject = Promise.reject(new Error('Быстрый провал'));

Promise.any([fastReject, slowSuccess])
    .then(value => console.log(value)) // Вывод: "Медленный успех"
    .catch(error => console.error(error));
// Reject быстрого Promise игнорируется, так как есть успешный.

4. При использовании Promise.race()"первый завершённый"

Promise.race() возвращает результат (или ошибку) первого завершённого Promise. Если первым завершается Promise с reject, Promise.race() немедленно отклоняется. Остальные Promise продолжают выполняться, но их результаты игнорируются.

const fastReject = Promise.reject(new Error('Первый — reject'));
const slowResolve = new Promise(resolve => 
    setTimeout(() => resolve('Второй — resolve'), 100)
);

Promise.race([fastReject, slowResolve])
    .catch(error => console.error('Победитель race:', error.message));
// Вывод: "Победитель race: Первый — reject"
// slowResolve всё равно выполнится, но будет проигнорирован.

5. При самостоятельном запуске (без комбинаторов)

Если Promise созданы и запущены независимо друг от друга, то отклонение одного не оказывает никакого влияния на выполнение остальных. Каждый Promise — изолированная асинхронная операция.

const independentPromise1 = new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Первый упал')), 50)
);
const independentPromise2 = new Promise(resolve => 
    setTimeout(() => {
        console.log('Второй выполнен, несмотря на ошибку первого');
        resolve('ОК');
    }, 100)
);

// Оба Promise выполнятся независимо.
independentPromise1.catch(e => console.error(e.message));
independentPromise2.then(v => console.log(v));

Ключевые выводы

  • Поведение системы определяется методом-комбинатором, а не самими Promise.
  • Promise.all() и Promise.race() прерывают общее ожидание при первом reject, но не останавливают выполнение остальных уже запущенных асинхронных операций.
  • Promise.allSettled() и Promise.any() являются более "толерантными" к ошибкам.
  • Незавершённые Promise могут приводить к потенциальным проблемам:
    *   **Утечки памяти**, если отклонённый Promise всё ещё удерживает ресурсы.
    *   **Неожиданные сайд-эффекты**, если фоновые операции изменяют общее состояние приложения.
  • Важно всегда обрабатывать ошибки каждого Promise, используя .catch() или try/catch с async/await, даже при групповой обработке, чтобы избежать непредвиденного поведения и незавершённых операций.

Для контроля над всеми операциями в сценарии с Promise.all() можно предварительно оборачивать каждый Promise в обработку ошибок, чтобы они никогда не отклонялись, или использовать отменяемые Promise (cancelable promises) с помощью AbortController, что является более современным и предпочтительным подходом.