Cегодня разберем одну из тем в JavaScript, это асинхронное программирование с помощью Promise и async/await. Ключевые инструменты для работы с запросами к серверу, обработкой данных и другими операциями, которые требуют времени.
Что такое промисы?
Промисы (Promise) это объекты, которые представляют результат асинхронной операции. Они помогают избежать «ада колбэков» (callback hell) и делают код чище и предсказуемее.
Как работает промис?
У промиса есть три состояния:
- Pending — ожидание (начальное состояние).
- Fulfilled — успешное выполнение.
- Rejected — выполнение с ошибкой.
Промис создается с помощью конструктора new Promise()
, который принимает функцию с двумя аргументами: resolve
(вызывается при успехе) и reject
(при ошибке).
Пример:
const myPromise = new Promise((resolve, reject) => { // Имитация асинхронной операции (например, запрос к серверу) setTimeout(() => { const success = true; if (success) { resolve("Данные успешно получены!"); } else { reject("Ошибка загрузки данных!"); } }, 2000); });
Обработка ошибок через .then() и .catch()
Промисы позволяют обрабатывать результаты и ошибки цепочкой методов.
.then()
Метод then()
принимает два аргумента:
- Функцию для обработки успешного результата.
- Функцию для обработки ошибки (необязательно, обычно используют
.catch()
).
Пример:
myPromise .then((result) => { console.log(result); // "Данные успешно получены!" }) .catch((error) => { console.error(error); // Сработает при вызове reject() });
Цепочки промисов
Методы можно объединять в цепочки для последовательных операций:
fetchData() .then(processData) .then(displayData) .catch(handleError);
Важно: Если в цепочке возникает ошибка, управление сразу переходит к ближайшему .catch()
.
Асинхронное программирование с async/await
async/await это синтаксический сахар над промисами, который делает код еще понятнее.
Ключевое слово async
Функция, объявленная с async
, всегда возвращает промис:
async function fetchData() { return "Данные загружены!"; } // Аналог: function fetchData() { return Promise.resolve("Данные загружены!"); }
Ключевое слово await
await
приостанавливает выполнение функции до выполнения промиса. Работает только внутри async
-функций.
Пример:
async function loadData() { try { const result = await myPromise; // Ждем выполнения промиса console.log(result); } catch (error) { console.error(error); } }
Обработка ошибок с try/catch
Для обработки ошибок в async/await используйте блок try/catch
:
async function loadUser() { try { const user = await fetchUser(); const posts = await fetchPosts(user.id); console.log(posts); } catch (error) { console.log("Ошибка:", error); } }
Практические задачи
Задача 1: Создайте промис
Напишите промис, который через 3 секунды возвращает случайное число от 1 до 10. Если число больше 5, вызывается resolve
, иначе — reject
.
Решение:
const numberPromise = new Promise((resolve, reject) => { setTimeout(() => { const num = Math.floor(Math.random() * 10) + 1; if (num > 5) { resolve(`Успех: ${num}`); } else { reject(`Ошибка: ${num}`); } }, 3000); }); numberPromise .then(console.log) .catch(console.error);
Задача 2: Цепочка промисов
Создайте функцию getUserData
, которая возвращает промис с объектом пользователя {id: 1, name: "Максим"}
. Затем напишите цепочку, которая преобразует имя в верхний регистр.
Решение:
function getUserData() { return Promise.resolve({ id: 1, name: "Максим" }); } getUserData() .then(user => { user.name = user.name.toUpperCase(); return user; }) .then(updatedUser => console.log(updatedUser));
Задача 3: Перепишите код на async/await
Дана функция fetchData
, возвращающая промис. Перепишите цепочку .then()
на async/await
.
Исходный код:
fetchData() .then(data => processData(data)) .then(result => console.log(result)) .catch(error => console.error(error));
Решение:
async function handleData() { try { const data = await fetchData(); const result = await processData(data); console.log(result); } catch (error) { console.error(error); } } handleData();
Советы
- Всегда обрабатывайте ошибки через
.catch()
илиtry/catch
. - Избегайте вложенных промисов — используйте цепочки или async/await.
- Помните:
await
можно использовать только вasync
-функциях.
Промисы и async/await это основа работы с асинхронным кодом в JavaScript. Практикуйтесь на реальных примерах, делайте запросы к API, обрабатывайте файлы и экспериментируйте!
Полный курс «JavaScript для начинающих» доступен здесь: https://max-gabov.ru/javascript-dlya-nachinaushih