Что такое 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 существует три возможных состояния:
-
Pending (ожидание)
Начальное состояние. Операция ещё не завершена.
resolve или reject ещё не были вызваны. -
Fulfilled (выполнено успешно)
Операция завершилась успешно, resolve был вызван.
Обещание возвращает результат (value), который можно обработать с помощью .then(). -
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
- .then(onFulfilled, onRejected)
Позволяет указать действия при успехе и/или при ошибке.
p.then(
result => console.log(result),
error => console.error(error)
);
- .catch(onRejected)
Обрабатывает только ошибку:
p.catch(error => console.error('Ошибка:', error));
- .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, что делает возможным цепочки.
⚠️ Особенности:
-
Promise однократен
Один resolve или reject, последующие вызовы игнорируются. -
Асинхронность по спецификации
Обработчики .then() и .catch() всегда выполняются асинхронно, даже если resolve() был вызван немедленно.
const p = Promise.resolve('Done');
p.then(console.log);
console.log('After');
// Output: After → Done
- Ошибка внутри .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
}
🧠 Промис — это не просто результат
Это контейнер, внутри которого временно находится результат или ошибка, с возможностью зарегистрировать обработчики результата в будущем, когда он появится. Это позволяет строить сложные асинхронные цепочки логики без вложенных колбэков.