Async/await — код который ждёт
Когда твой код шлёт запрос к API — ответ приходит через 100-500мс. JavaScript на это время не «зависает» — он умеет ждать асинхронно. Async/await — современный синтаксис для работы с этим. Без него непонятна почти ни одна функция в AI-коде, которая обращается к серверу.
Promise — обещание результата
Promise — это «коробочка», в которой когда-нибудь появится значение (или ошибка). Когда вызываешь fetch(url) — он СРАЗУ возвращает Promise, не данные. Внутри Promise может быть три состояния: pending (ещё ждём), fulfilled (готово), rejected (ошибка). Тебе нужно «открыть» Promise когда он будет готов.
await — «подожди и дай результат»
JS ставит код на паузу пока Promise не станет готов, потом записывает значение в переменную. Внешне похоже на синхронный код, но JS под капотом не блокирует ничего — другие задачи продолжают идти. await работает ТОЛЬКО внутри функции, помеченной async. Без async — синтаксическая ошибка.
async function
Префикс async перед функцией: 1) разрешает использовать await внутри, 2) автоматически оборачивает возвращаемое значение в Promise. То есть
возвращает Promise<number>, а не number. Чтобы вызвать другую async-функцию из обычной — либо тоже сделать её async, либо использовать .then().
try/catch для ошибок
Если запрос провалился (нет интернета, 500 от сервера) — Promise отклоняется, и await БРОСАЕТ ошибку. Ловим обычным try/catch:
Без try/catch ошибка «всплывёт» до вызывающей функции и так далее. Игнорировать нельзя — иначе невидимый сбой.
Параллельно vs последовательно
запросы идут друг за другом (1.5с + 1.5с = 3с). Если они независимы — гоняй параллельно:
стартуют одновременно (≈ 1.5с). Это частая оптимизация, ИИ её не всегда применяет — можешь сам.
// === БАЗОВЫЙ ВАРИАНТ ===
async function getUser(id) {
const r = await fetch(`/api/users/${id}`);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const data = await r.json(); // .json() тоже Promise!
return data;
}
// Использование
try {
const user = await getUser(42);
console.log(user.name);
} catch (e) {
console.error('Не удалось:', e.message);
}
// === ПОСЛЕДОВАТЕЛЬНО vs ПАРАЛЛЕЛЬНО ===
// ПЛОХО — последовательно, медленно
async function loadDashboardSlow() {
const user = await fetch('/api/me').then(r => r.json()); // 200мс
const orders = await fetch('/api/orders').then(r => r.json()); // ждём 200
const news = await fetch('/api/news').then(r => r.json()); // ждём 200
return { user, orders, news };
// Итого: 600мс
}
// ХОРОШО — параллельно
async function loadDashboardFast() {
const [user, orders, news] = await Promise.all([
fetch('/api/me').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/news').then(r => r.json()),
]);
return { user, orders, news };
// Итого: 200мс — все три стартуют одновременно
}
// === ОБРАБОТКА В ЦИКЛЕ ===
// for-of с await — последовательно (когда нужна очерёдность)
for (const id of ids) {
await processOne(id); // ждём каждый перед следующим
}
// Promise.all с .map — параллельно (когда независимы)
await Promise.all(ids.map(id => processOne(id)));
// === ИИ часто пишет так — узнавай ===
async function safeRequest(url) {
try {
const r = await fetch(url);
if (!r.ok) return null; // или throw — выбор стиля
return await r.json();
} catch (e) {
console.error(e);
return null;
}
}Типичные паттерны async/await — есть и хорошие, и неоптимальные