Кратко
Promise — объект, представляющий результат операции, который станет известен позже. У него три состояния: pending (ожидание), fulfilled (выполнено), rejected (ошибка). then обрабатывает успех, catch — ошибку, finally — завершение в любом случае.
Подробно
Создание Promise: const promise = new Promise((resolve, reject) => { // Асинхронная операция setTimeout(() => { resolve('Успех!'); // fulfilled // или reject('Ошибка!'); // rejected }, 1000); });
Три состояния:
- Pending — операция выполняется
- Fulfilled — resolve вызван → результат доступен
- Rejected — reject вызван → ошибка доступна
После fulfilled/rejected состояние НЕ меняется.
Использование: promise .then(result => console.log(result)) // 'Успех!' .catch(error => console.log(error)) .finally(() => console.log('Завершено'));
Цепочка then: fetchUser(1) .then(user => fetchPosts(user.id)) .then(posts => console.log(posts)) .catch(error => console.log(error));
Каждый .then возвращает НОВЫЙ Promise.
Promise.all: const p1 = fetch('/api/users'); const p2 = fetch('/api/posts'); Promise.all([p1, p2]) .then(([users, posts]) => { /* оба готовы */ }) .catch(error => { /* хотя бы один отклонён */ });
Ментальная модель
Promise — как квитанция в ресторане. Вы сделали заказ (вызвали Promise). Вам дали квитанцию (Promise object). Когда еда готова (resolve) — вам принесут блюдо (result). Если кухня закрылась (reject) — вам сообщат об ошибке. Вы можете пойти гулять (другий код выполняется) пока ждёте.
Примеры
**Самый простой:**
const promise = new Promise((resolve) => {
setTimeout(() => resolve('Готово!'), 1000);
});
promise.then(result => console.log(result));
// Через 1 сек: 'Готово!'Простейший Promise: resolve через 1 секунду.
**Простой:**
function divide(a, b) {
return new Promise((resolve, reject) => {
if (b === 0) {
reject(new Error('Деление на ноль!'));
} else {
resolve(a / b);
}
});
}
divide(10, 2)
.then(result => console.log(result)) // 5
.catch(error => console.log(error.message));
divide(10, 0)
.then(result => console.log(result))
.catch(error => console.log(error.message)); // 'Деление на ноль!'Promise с валидацией: resolve для успеха, reject для ошибки.
**Реальный пример:**
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId > 0) {
resolve({ id: userId, name: 'Анна', email: 'anna@test.com' });
} else {
reject(new Error('Неверный ID'));
}
}, 500);
});
}
// Цепочка промисов:
fetchUserData(1)
.then(user => {
console.log(`Загружен: ${user.name}`);
return fetchUserData(2);
})
.then(user => {
console.log(`Загружен: ${user.name}`);
})
.catch(error => {
console.log(`Ошибка: ${error.message}`);
})
.finally(() => {
console.log('Загрузка завершена');
});Цепочка then: каждый шаг возвращает новый Promise.
Частые ошибки
**Неправильно:** Забывать catch в цепочке then
**Почему:** Без catch ошибка промиса «зависает» — не обрабатывается.
**Правильно:** Всегда завершайте цепочку .catch() или используйте try/catch с async/await.
**Неправильно:** Думать, что Promise автоматически делает код async
**Почему:** Promise — это ОБЪЕКТ, представляющий результат. Код внутри new Promise выполняется синхронно до первого асинхронного действия.
**Правильно:** Promise — обёртка для результата, который приходит позже.
**Неправильно:** Вызывать resolve/reject несколько раз
**Почему:** Только первый вызов имеет эффект. Остальные игнорируются.
**Правильно:** resolve/reject — одноразовые. Один промис — одно решение.
Важно запомнить
- Promise: pending → fulfilled или rejected
- resolve(result) — успешное завершение
- reject(error) — ошибка
- .then() — обработка успеха
- .catch() — обработка ошибки
- .finally() — завершение в любом случае
- Каждый .then возвращает новый Promise
Связь
Назад: Вы понимаете callback-функции и таймеры (JA1-JA3) — промисы это структурированный способ обработки асинхронных результатов.
Вперёд: Следующий урок (JA5) — async/await: синтаксический сахар над промисами.