Промисы
Объект-обещание, который распрямляет лесенку колбэков в читаемую цепочку.
Promise (промис) — это объект, представляющий результат асинхронной операции, который появится в будущем: либо успешно (resolved), либо с ошибкой (rejected).
Три состояния промиса
Промис всегда находится в одном из трёх состояний:
- pending — ожидание, операция ещё идёт;
- fulfilled — выполнен успешно, есть результат;
- rejected — завершился ошибкой.
Из pending промис переходит в одно из конечных состояний ровно один раз и больше не меняется. Это важное свойство: если промис уже разрешился успехом, повторно «упасть» он не сможет, и наоборот. Поэтому промис безопасно передавать в разные части программы — каждый получит один и тот же финальный результат, а не запустит операцию заново.
then и catch
Результат успешного промиса забирают через .then, ошибку — через .catch:
const promise = new Promise((resolve, reject) => {
const ok = true;
if (ok) {
resolve("успех");
} else {
reject("провал");
}
});
promise
.then((result) => console.log("Готово:", result))
.catch((error) => console.log("Ошибка:", error));
Вывод:
Готово: успех
Цепочки вместо лесенки
Главное преимущество: .then можно выстраивать в цепочку. Если в .then вернуть новый промис, следующий .then дождётся его. Так зависимые операции выстраиваются ровно вниз, а не вправо:
function step(name, value) {
return Promise.resolve(value).then((v) => {
console.log(name, "->", v);
return v + 1;
});
}
step("шаг 1", 10)
.then((v) => step("шаг 2", v))
.then((v) => step("шаг 3", v))
.then((v) => console.log("итог:", v));
Вывод:
шаг 1 -> 10 шаг 2 -> 11 шаг 3 -> 12 итог: 13
Сравните с callback hell из прошлого урока — здесь шаги читаются сверху вниз, а одна .catch в конце поймает ошибку с любого этапа.
Promise.all — несколько дел сразу
Если операции независимы, их запускают параллельно через Promise.all. Он ждёт, пока выполнятся ВСЕ, и отдаёт массив результатов:
const p1 = Promise.resolve("пользователь");
const p2 = Promise.resolve("настройки");
const p3 = Promise.resolve("уведомления");
Promise.all([p1, p2, p3]).then((results) => {
console.log("Все загружены:", results);
});
Вывод:
Все загружены: [ 'пользователь', 'настройки', 'уведомления' ]
Это быстрее, чем грузить по очереди: все три «уехали» одновременно. Если хоть один промис упадёт, Promise.all сразу перейдёт в .catch. Когда же вам нужны результаты всех операций независимо от того, какие из них упали, берут Promise.allSettled — он дожидается всех и для каждого сообщает, успех это был или ошибка.
Итог
- Промис — обещание будущего результата: pending → fulfilled / rejected.
- Успех ловят через
.then, ошибку — через.catch. - Цепочка
.thenзаменяет вложенные колбэки плоской последовательностью. Promise.allзапускает независимые операции параллельно и ждёт все.