Асинхронность в JavaScript нужна, когда операция выполняется не мгновенно: запрос к API, чтение файла, таймер, работа с базой данных. Главная цель — не блокировать основной поток и не «замораживать» интерфейс.
Раньше для этого часто использовали колбэки, но они быстро превращались в callback hell: вложенность растёт, ошибки ловить неудобно, код читать тяжело. Здесь на помощь пришли Promise и async/await 🚀
Promise — это объект, который представляет результат асинхронной операции:
- pending — ожидание
- fulfilled — выполнено успешно
- rejected — выполнено с ошибкой
Пример:
fetch('/api/user')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
Такой код уже лучше колбэков: цепочка читается сверху вниз, ошибки можно централизованно обрабатывать через .catch().
async/await — это синтаксический сахар над Promise. Он делает асинхронный код похожим на синхронный и заметно улучшает читаемость.
Пример:
async function getUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
Почему разработчики любят async/await 💡
- код проще читать и поддерживать
- удобно работать с try/catch
- меньше вложенности
- легче писать последовательные шаги логики
Но важно понимать: await не делает код синхронным на самом деле. Он лишь приостанавливает выполнение внутри конкретной async-функции, не блокируя весь JavaScript runtime.
Где часто ошибаются ⚠️
- Забывают await — получают Promise вместо результата
- Не обрабатывают ошибки — приложение падает или ведёт себя непредсказуемо
- Используют await в цикле без необходимости — запросы идут последовательно и тормозят выполнение
Например, если задачи независимы, лучше так:
const [user, posts] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
Это быстрее, чем ждать каждый запрос по очереди. ⚡
Когда использовать что:
- Promise.then() — если нужна короткая цепочка
- async/await — если логика сложнее, есть ветвления, циклы, обработка ошибок
- Promise.all() — когда нужно запустить несколько независимых операций параллельно
Итог: Promise — это фундамент асинхронности в современном JS, а async/await — самый удобный способ с ним работать. Если понимать разницу между последовательным и параллельным выполнением, можно писать не только красивый, но и быстрый код 🧠
👀 Ниже стоит заглянуть в подборку каналов про IT — там много полезного по JavaScript, backend, frontend и архитектуре.