Promise (базово)
Урок: Promise
Введение
В предыдущем уроке мы говорили об асинхронности — о том, как программа может выполнять задачи без остановки.
Но возникает следующая проблема: как работать с результатом асинхронной операции?
Представь, что ты заказал доставку еды. Ты не знаешь точно, когда она приедет, но у тебя есть «обещание», что она будет доставлена — либо успешно, либо с ошибкой.
В программировании ситуация похожая. Когда мы отправляем запрос на сервер, мы не получаем результат сразу. Но нам нужен способ:
- дождаться результата,
- обработать его,
- или обработать ошибку.
Для этого в JavaScript существует Promise.
Что такое Promise на практике
Promise — это объект, который представляет результат асинхронной операции.
Проще говоря, это «обещание», что операция завершится:
- либо успешно,
- либо с ошибкой.
У Promise есть три состояния:
- ожидание (pending),
- выполнено успешно (fulfilled),
- выполнено с ошибкой (rejected).
Но важнее понять не термины, а идею: Promise — это контейнер для будущего результата.
Создание простого Promise и then
Рассмотрим пример, который полностью выполняется в одном фрагменте: создаём Promise и сразу подписываемся на результат.
let promise = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve('Готово!');
}, 2000);
});
promise.then(function (result) {
console.log(result);
});
Разберём:
new Promise(...)— создаём новый Promise;- внутрь передаётся функция;
resolve— функция, которая сообщает об успешном завершении;reject— функция, которая сообщает об ошибке;thenподписывается на успех: когда вызоветсяresolve, в колбэк придёт значение.
Через 2 секунды вызывается resolve('Готово!') — в консоли появится Готово!.
Обработка ошибок через catch
Если что-то пошло не так, используется reject.
let promise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject('Ошибка!');
}, 2000);
});
promise.catch(function (error) {
console.log(error);
});
Результат:
Ошибка!
Метод catch срабатывает, если Promise завершился с ошибкой.
Цепочка then
Одна из сильных сторон Promise — возможность строить цепочки.
let promise = new Promise(function (resolve) {
resolve(2);
});
promise
.then(function (num) {
return num * 2;
})
.then(function (num) {
return num * 3;
})
.then(function (result) {
console.log(result);
});
Результат:
12
Разберём:
- первый
thenполучает 2 → возвращает 4; - второй получает 4 → возвращает 12;
- третий получает 12 → выводит результат.
Каждый then получает результат предыдущего.
Более короткая запись (стрелочные функции)
Часто Promise пишут с использованием стрелочных функций:
let promise = new Promise((resolve) => {
resolve(5);
});
promise.then((num) => num * 2).then((num) => console.log(num));
Это тот же код, но более компактный.
Пример с имитацией запроса
Представим, что мы «загружаем данные»:
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('Данные получены');
}, 2000);
});
}
fetchData().then((data) => {
console.log(data);
});
Результат через 2 секунды:
Данные получены
Здесь:
- функция возвращает Promise;
thenполучает результат;- код не блокируется.
Почему Promise лучше callback
Ранее для асинхронности использовали callback-функции:
setTimeout(() => {
console.log('Готово');
}, 2000);
Но при сложной логике получаются вложенные функции. Ниже — учебная имитация: простые шаги вызывают следующий колбэк (в реальности вместо cb() могли бы быть таймеры или запросы).
function step1(cb) {
cb();
}
function step2(cb) {
cb();
}
function step3(cb) {
cb();
}
step1(() => {
step2(() => {
step3(() => {
console.log('Готово');
});
});
});
Это называется «callback hell».
Promise решает эту проблему, делая код последовательным и читаемым через цепочки then.
Где это используется на практике
Promise используется везде, где есть асинхронность:
- запросы к серверу (fetch, axios);
- работа с файлами;
- таймеры;
- взаимодействие с API;
- загрузка данных.
Практически любая современная библиотека или API работает через Promise.
Итоговое понимание
Promise — это способ работать с результатом асинхронной операции.
Он позволяет:
- дождаться результата;
- обработать успех или ошибку;
- строить цепочки действий.
Ключевая идея в том, что Promise — это «обещание результата в будущем». Мы не получаем данные сразу, но можем заранее описать, что делать, когда они появятся.
Это делает асинхронный код более понятным, управляемым и последовательным.