Промисы (Promise)
Промис (Promise) — это встроенный в JavaScript объект, который представляет результат асинхронной операции, которая может завершиться успешно или с ошибкой. Промисы были созданы для решения проблем коллбэков и обеспечения более читаемого и управляемого асинхронного кода.
Состояния промиса
Любой промис может находиться в одном из трёх состояний:
- pending — начальное состояние, операция ещё не завершена
- fulfilled — операция завершилась успешно, значение доступно
- rejected — операция завершилась с ошибкой, причина ошибки доступна
Состояние промиса меняется только один раз: из pending либо в fulfilled, либо в rejected. После этого оно остаётся неизменным.
Создание промиса
Промис создаётся с помощью конструктора new Promise(), которому передаётся функция-исполнитель (executor):
const myPromise = new Promise((resolve, reject) => {
// Имитация асинхронной операции
setTimeout(() => {
const success = true;
if (success) {
resolve('Данные получены');
} else {
reject(new Error('Не удалось получить данные'));
}
}, 1000);
});
Функция получает два параметра:
resolve(value)— вызывается при успешном завершенииreject(error)— вызывается при ошибке
Обработка результата
Для работы с результатом промиса используются методы:
.then()
Вызывается, если промис выполнен успешно:
myPromise.then((result) => {
console.log(result); // 'Данные получены'
});
.catch()
Вызывается, если промис отклонён:
myPromise.catch((error) => {
console.error(error.message); // 'Не удалось получить данные'
});
.finally()
Вызывается в любом случае — как при успехе, так и при ошибке. Часто используется для очистки (например, скрыть индикатор загрузки):
myPromise
.then(console.log)
.catch(console.error)
.finally(() => console.log('Операция завершена'));
Цепочка промисов
Метод .then() возвращает новый промис, что позволяет строить цепочки:
fetchUserData()
.then(user => fetchUserPosts(user.id))
.then(posts => processPosts(posts))
.then(result => console.log(result))
.catch(error => console.error('Ошибка:', error));
Каждый шаг может возвращать значение или другой промис. Если в цепочке возникает ошибка, выполнение переходит к ближайшему .catch().
Преимущества перед коллбэками
- Код становится линейным и читаемым
- Ошибки обрабатываются централизованно через
.catch() - Легко комбинировать несколько асинхронных операций
- Избегается «ад коллбэков»
Важно помнить
- Промисы не отменяются после создания
- Нельзя узнать текущее состояние промиса напрямую (только через обработчики)
- Если не вызвать
.catch(), ошибка может остаться незамеченной (в современных средах такие ошибки логируются в консоль)
Промисы стали стандартом для асинхронных операций в JavaScript и лежат в основе более современного синтаксиса async/await.