Что такое Promise в JavaScript?

JuniorJavaScript · Frontend·Обновлено 19 июня 2026
Коротко
Promise — это объект, представляющий результат асинхронной операции, который может находиться в одном из трёх состояний: pending, fulfilled или rejected. Он позволяет работать с асинхронным кодом более удобно, чем с колбэками, избегая «callback hell».

Что такое Promise

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

Главная идея — отделить запуск асинхронной операции от обработки её результата. Вместо того чтобы передавать колбэки внутрь функции, мы получаем объект, на который можно «подписаться» через методы .then(), .catch() и .finally().

Три состояния промиса

Promise всегда находится в одном из трёх состояний:

  • pending (ожидание) — начальное состояние, операция ещё не завершена.
  • fulfilled (выполнен) — операция завершилась успешно, промис получил значение.
  • rejected (отклонён) — операция завершилась с ошибкой.

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

Создание промиса

Промис создаётся через конструктор new Promise(), в который передаётся функция-исполнитель с двумя аргументами: resolve и reject.

const promise = new Promise((resolve, reject) => {
  // имитируем асинхронную операцию
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve('Данные получены');
    } else {
      reject(new Error('Что-то пошло не так'));
    }
  }, 1000);
});

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

  • .then(onFulfilled, onRejected) — регистрирует обработчики успеха и ошибки.
  • .catch(onRejected) — обработчик только для ошибок (эквивалент .then(null, onRejected)).
  • .finally(onFinally) — выполняется в любом случае, удобно для очистки ресурсов.

Каждый из этих методов возвращает новый промис, что позволяет строить цепочки.

fetch('/api/user')
  .then((response) => response.json())
  .then((user) => console.log(user.name))
  .catch((error) => console.error('Ошибка:', error))
  .finally(() => console.log('Запрос завершён'));

Статические методы

Класс Promise предоставляет полезные статические методы для работы с группами промисов:

  • Promise.all([...]) — ждёт все промисы; падает, если хотя бы один отклонён.
  • Promise.allSettled([...]) — ждёт завершения всех, возвращает массив результатов.
  • Promise.race([...]) — возвращает результат первого завершившегося промиса.
  • Promise.any([...]) — возвращает первый успешный промис.
  • Promise.resolve(value) и Promise.reject(reason) — создают уже улаженный промис.

Микрозадачи и event loop

Обработчики .then/.catch/.finally выполняются как микрозадачи (microtasks). Это значит, что они запускаются после текущего синхронного кода, но раньше любых макрозадач (например, setTimeout). Понимание этой очерёдности важно для отладки асинхронного кода.

Связь с async/await

Синтаксис async/await — это «синтаксический сахар» над промисами. Функция, помеченная async, всегда возвращает промис, а await приостанавливает выполнение до его улаживания, делая асинхронный код визуально похожим на синхронный.

Что хочет услышать интервьюер

Определение Promise как объекта, представляющего результат будущей асинхронной операции

Перечисление трёх состояний: pending, fulfilled, rejected — и понимание, что переход необратим

Знание методов .then(), .catch(), .finally() и возможность строить цепочки

Понимание статических методов: Promise.all, allSettled, race, any

Связь промисов с async/await и понимание, что обработчики — это микрозадачи

Пример: Создание и использование промиса

// функция, возвращающая промис с задержкой
function delay(ms: number): Promise<string> {
  return new Promise((resolve, reject) => {
    if (ms < 0) {
      reject(new Error('Отрицательная задержка недопустима'));
      return;
    }
    setTimeout(() => resolve(`Прошло ${ms} мс`), ms);
  });
}

// использование через цепочку .then
delay(500)
  .then((message) => console.log(message))
  .catch((error) => console.error(error.message))
  .finally(() => console.log('Готово'));

Пример: Параллельное выполнение с Promise.all и allSettled

// загружаем несколько ресурсов параллельно
async function loadDashboard() {
  try {
    // Promise.all падает при первой же ошибке
    const [user, posts] = await Promise.all([
      fetch('/api/user').then((r) => r.json()),
      fetch('/api/posts').then((r) => r.json()),
    ]);
    console.log(user, posts);
  } catch (error) {
    console.error('Один из запросов упал:', error);
  }

  // allSettled дождётся всех, ошибки не прерывают остальные
  const results = await Promise.allSettled([
    fetch('/api/a'),
    fetch('/api/b'),
  ]);
  results.forEach((result) => {
    if (result.status === 'fulfilled') {
      console.log('OK:', result.value);
    } else {
      console.warn('Ошибка:', result.reason);
    }
  });
}

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

Путают вызов resolve/reject с возвратом значения из исполнителя — return не влияет на состояние промиса

Забывают про .catch() и теряют ошибки, получая UnhandledPromiseRejection

Считают, что промис можно «отменить» или повторно изменить состояние после settle

Не понимают разницу между Promise.all и Promise.allSettled, теряя данные при одной ошибке

Возвращают из .then() не значение или промис, а сам объект промиса в обёртке, ломая цепочку

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.5
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее