async/await
Самый удобный способ писать асинхронный код — как будто он синхронный.
async/await — это синтаксис поверх промисов:
await«ждёт» результат промиса, а код выглядит линейно, как обычный.
Та же логика, но читается линейно
Промисы убрали лесенку колбэков, но цепочки .then всё ещё многословны. async/await идёт дальше: асинхронный код выглядит как обычный, сверху вниз.
Функцию помечают словом async, а внутри неё перед промисом ставят await — выполнение «приостановится» на этой строке, пока промис не разрешится:
function delay(value) {
return Promise.resolve(value);
}
async function run() {
const a = await delay(10);
const b = await delay(a + 5);
const c = await delay(b + 5);
console.log("Результат:", c);
}
run();
Вывод:
Результат: 20
Никаких .then — каждая строка ждёт предыдущую. Читается как обычная последовательность шагов.
Обработка ошибок через try/catch
С await ошибки ловят привычным try/catch, как в синхронном коде, — не нужно помнить про .catch на каждом шаге:
async function risky() {
return Promise.reject(new Error("что-то сломалось"));
}
async function main() {
try {
await risky();
} catch (err) {
console.log("Поймали ошибку:", err.message);
}
console.log("Программа продолжает работу");
}
main();
Вывод:
Поймали ошибку: что-то сломалось Программа продолжает работу
async-функция всегда возвращает промис
Под капотом async/await — это всё те же промисы, просто с приятным синтаксисом: движок сам разворачивает их за вас. Поэтому два стиля полностью совместимы. Результат async-функции можно дождаться как через await, так и через .then, а внутри async-функции можно вызывать обычные функции, возвращающие промис.
Важный момент: что бы вы ни вернули из async-функции, наружу выйдет промис. Поэтому её результат тоже забирают через await или .then:
async function getNumber() {
return 42; // обернётся в промис автоматически
}
async function show() {
const n = await getNumber();
console.log("Число:", n);
}
show();
Вывод:
Число: 42
Параллельность не теряем
Если писать await подряд, операции пойдут последовательно. Когда они независимы, лучше запустить их сразу и дождаться через Promise.all:
async function loadAll() {
// запускаем все три сразу, ждём вместе
const [a, b, c] = await Promise.all([
Promise.resolve("A"),
Promise.resolve("B"),
Promise.resolve("C")
]);
console.log(a, b, c);
}
loadAll();
Вывод:
A B C
Эволюция асинхронности
| Подход | Минус |
| Колбэки | callback hell, ручная обработка ошибок |
| Промисы | цепочки .then многословны |
| async/await | почти нет — это рекомендуемый стиль |
Итог
asyncпомечает функцию,awaitждёт результат промиса внутри неё.- Код выглядит линейно, как синхронный, но не блокирует поток.
- Ошибки ловят обычным
try/catch. - Для параллельных задач сочетают
awaitсPromise.all.