Что такое promise и какие состояния у него есть

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

📌 Что такое Promise

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

const promise = new Promise((resolve, reject) => {
// асинхронный код
});

Аргументы resolve и reject — это функции:

  • resolve(value) — переводит promise в состояние fulfilled (успешно выполнено),

  • reject(error) — переводит его в состояние rejected (ошибка).

📋 Состояния Promise

У объекта Promise существует три возможных состояния:

  1. Pending (ожидание)
    Начальное состояние. Операция ещё не завершена.
    resolve или reject ещё не были вызваны.

  2. Fulfilled (выполнено успешно)
    Операция завершилась успешно, resolve был вызван.
    Обещание возвращает результат (value), который можно обработать с помощью .then().

  3. Rejected (отклонено)
    Операция завершилась с ошибкой, был вызван reject(error).
    Ошибку можно перехватить с помощью .catch().

После перехода из pending в fulfilled или rejected, состояние становится неизменным (immutable) — то есть промис больше не может изменить своё состояние.

📘 Пример

const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success');
}, 1000);
});
p.then(result => console.log(result)); // Через 1 секунду: "Success"

📌 Методы работы с Promise

  1. .then(onFulfilled, onRejected)
    Позволяет указать действия при успехе и/или при ошибке.
p.then(
result => console.log(result),
error => console.error(error)
);
  1. .catch(onRejected)
    Обрабатывает только ошибку:
p.catch(error => console.error('Ошибка:', error));
  1. .finally(callback)
    Вызывается в любом случае — и при resolve, и при reject.
p.finally(() => console.log('Завершено'));

📌 Promise chaining (цепочки)

Методы .then() можно вызывать последовательно:

new Promise((resolve) => {
resolve(2);
})
.then(val => val \* 2) // 4
.then(val => val + 1) // 5
.then(val => console.log(val)); // 5

Каждый .then() возвращает новый promise, что делает возможным цепочки.

⚠️ Особенности:

  1. Promise однократен
    Один resolve или reject, последующие вызовы игнорируются.

  2. Асинхронность по спецификации
    Обработчики .then() и .catch() всегда выполняются асинхронно, даже если resolve() был вызван немедленно.

const p = Promise.resolve('Done');
p.then(console.log);
console.log('After');
// Output: After  Done
  1. Ошибка внутри .then() = reject
Promise.resolve()
.then(() => {
throw new Error('Что-то пошло не так');
})
.catch(error => console.log('Поймали:', error.message));

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

  • Promise.resolve(value) — создаёт Promise, немедленно переходящий в fulfilled.

  • Promise.reject(error) — создаёт Promise, немедленно переходящий в rejected.

  • Promise.all(iterable) — ждёт, пока все промисы выполнятся, или один завершится с ошибкой.

  • Promise.race(iterable) — возвращает результат первого выполненного (или отклонённого) промиса.

  • Promise.allSettled(iterable) — ждёт завершения всех промисов, возвращает массив объектов с их статусами.

  • Promise.any(iterable) — возвращает первый успешно выполненный промис, игнорирует ошибки, пока не останется ни одного.

📘 Пример: Promise.all

const p1 = Promise.resolve(1);
const p2 = new Promise(res => setTimeout(() => res(2), 1000));
const p3 = Promise.resolve(3);
Promise.all(\[p1, p2, p3\])
.then(results => console.log(results)); // \[1, 2, 3\] через 1 секунду

📘 Пример: Обработка ошибки

const faulty = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('Ошибка')), 1000);
});
faulty
.then(result => console.log(result))
.catch(err => console.log('Произошла ошибка:', err.message));

💡 Взаимодействие с async/await

async функция всегда возвращает Promise. Внутри можно использовать await для ожидания результата промиса:

async function example() {
const result = await Promise.resolve(42);
console.log(result); // 42
}

🧠 Промис — это не просто результат

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