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

Какие знаешь состояния промиса?

2.0 Middle🔥 211 комментариев
#Soft Skills и рабочие процессы

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

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

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

Состояния Promise в JavaScript

Promise (Обещание) — это объект в JavaScript, представляющий результат асинхронной операции, который может быть еще недоступен. У Promise есть три основных состояния, которые определяют его жизненный цикл.

Три состояния Promise

  1. pending (ожидание)
    Исходное состояние промиса. Означает, что асинхронная операция еще не завершена, и результат неизвестен. Промис остается в этом состоянии, пока операция не завершится успешно или с ошибкой.

  2. fulfilled (выполнено)
    Промис переходит в это состояние, когда асинхронная операция завершилась успешно. Результат операции сохраняется в промис и становится доступным для обработки. В этом состоянии говорят, что промис "разрешен" (resolved) с значением.

  3. rejected (отклонено)
    Промис переходит в это состояние, если асинхронная операция завершилась с ошибкой. Причина ошибки (обычно объект Error) сохраняется в промис для последующей обработки.

Нюансы терминологии

Важно различать:

  • fulfilled — успешное выполнение с результатом
  • rejected — выполнение с ошибкой
  • settled — общее завершенное состояние (либо fulfilled, либо rejected)

Промис не может перейти из fulfilled в rejected или наоборот. После перехода в завершенное состояние (settled) его состояние и результат фиксируются навсегда.

Практический пример с кодом

// Промис в состоянии pending
const pendingPromise = new Promise((resolve, reject) => {
  // Асинхронная операция еще не завершена
  console.log('Промис создан, состояние: pending');
});

// Промис переходит в fulfilled
const fulfilledPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Данные успешно получены');
  }, 1000);
});

fulfilledPromise.then(result => {
  console.log('Промис fulfilled с результатом:', result);
});

// Промис переходит в rejected
const rejectedPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Ошибка сети'));
  }, 1000);
});

rejectedPromise.catch(error => {
  console.log('Промис rejected с ошибкой:', error.message);
});

Методы для работы с состояниями

  1. then() — обрабатывает переход в состояние fulfilled
  2. catch() — обрабатывает переход в состояние rejected
  3. finally() — выполняется в любом случае, когда промис завершается (settled)
asyncOperation()
  .then(data => {
    // Выполняется при fulfilled
    console.log('Успех:', data);
  })
  .catch(error => {
    // Выполняется при rejected
    console.error('Ошибка:', error);
  })
  .finally(() => {
    // Выполняется всегда при settled
    console.log('Операция завершена');
  });

Проверка состояния Promise

Стоит отметить, что в JavaScript нет прямого публичного API для проверки текущего состояния промиса. Однако можно использовать обходные методы:

// Создание промиса с отслеживанием состояния
function createTrackablePromise(executor) {
  let state = 'pending';
  
  const promise = new Promise((resolve, reject) => {
    executor(
      value => {
        state = 'fulfilled';
        resolve(value);
      },
      reason => {
        state = 'rejected';
        reject(reason);
      }
    );
  });
  
  // Мето для проверки состояния (нестандартный подход)
  promise.getState = () => state;
  
  return promise;
}

const trackablePromise = createTrackablePromise((resolve, reject) => {
  setTimeout(() => resolve('Готово!'), 500);
});

console.log('Начальное состояние:', trackablePromise.getState()); // pending
trackablePromise.then(() => {
  console.log('Конечное состояние:', trackablePromise.getState()); // fulfilled
});

Особенности в современных реализациях

В современных браузерах и Node.js:

  • Промисы являются неотменяемыми по умолчанию (хотя есть предложение для Cancelable Promises)
  • Состояние промиса иммутабельно после перехода в fulfilled или rejected
  • Микрозадачи (microtasks) — промисы используют очередь микрозадач для обработки then/catch/finally, что обеспечивает более высокий приоритет по сравнению с макрозадачами (setTimeout, setInterval)

Распространенные антипаттерны

// ❌ Плохо: создание "зависшего" промиса
const hangingPromise = new Promise(() => {
  // Никогда не вызывается ни resolve, ни reject
  // Промис вечно останется в состоянии pending
});

// ❌ Плохо: игнорирование состояния rejected
somePromise.then(data => {
  // Если промис rejected, ошибка будет "проглочена"
});

// ✅ Хорошо: всегда обрабатывайте возможные ошибки
somePromise
  .then(data => processData(data))
  .catch(error => handleError(error));

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

Какие знаешь состояния промиса? | PrepBro