Що робить await
await - це оператор, який призупиняє виконання async-функції, доки проміс не виконається (fulfilled) або не буде відхилений (rejected). Після цього await або повертає результат проміса, або викидає помилку, як звичайний throw.
Теорія
TL;DR
awaitчекає на завершення проміса всерединіasync-функції.- Якщо проміс виконано успішно,
awaitповертає його результат. - Якщо проміс відхилено,
awaitвикидає помилку, і її ловитьtry...catch. - Працює тільки всередині
async-функцій або як top-level await у модулях. - Не блокує потік: інший код продовжує виконуватися, поки функція «стоїть на паузі».
- Зі звичайним значенням теж працює: воно загортається в
Promise.resolve(value).
Швидкий приклад
let result = await promise; // тільки всередині async-функції або top-level await
async function example() {
console.log('Перед await');
const value = await Promise.resolve('Готово');
console.log('Після await:', value);
}
example();Синтаксис і що повертає await
let result = await promise;Працює тільки всередині async-функцій (або в top-level await у модулях).
Приклад 1, очікування проміса
async function example() {
console.log('Перед await');
const result = await Promise.resolve('Готово');
console.log('Після await:', result);
}
example();Вивід:
Перед await
Після await: Готовоawait чекає на виконання проміса і повертає 'Готово'.
Приклад 6, зі значеннями, що не є промісами. Якщо передати звичайне значення, воно негайно загортається в Promise.resolve():
async function demo() {
const result = await 42;
console.log(result);
}
demo(); // 42Це потрібно для уніфікації: await завжди працює так, ніби перед ним проміс.
Приклад 7, вкладені await
async function inner() {
return 'Всередині';
}
async function outer() {
const res = await inner();
console.log('Результат:', res);
}
outer();Вивід:
Результат: ВсерединіОскільки inner() повертає проміс, await просто чекає на його завершення.
Помилка: reject перетворюється на виняток
Приклад 2, помилка через await
async function fail() {
try {
const res = await Promise.reject('Помилка!');
} catch (err) {
console.error('Спіймали:', err);
}
}
fail();Вивід:
Спіймали: Помилка!Якщо проміс відхилено, await кидає виняток, тому помилки зручно ловити через try...catch.
Послідовно чи паралельно
Приклад 3, послідовне виконання
async function steps() {
console.log('1');
await new Promise(res => setTimeout(res, 1000));
console.log('2');
await new Promise(res => setTimeout(res, 1000));
console.log('3');
}
steps();Вивід:
1
(через 1 секунду)
2
(через 1 секунду)
3Кожен await чекає на завершення попереднього проміса, тому код працює послідовно.
Приклад 4, паралельне виконання (без await одразу)
async function parallel() {
const a = fetch('/api/user');
const b = fetch('/api/posts');
// обидва виконуються одночасно
const [user, posts] = await Promise.all([a, b]);
console.log('Обидва запити завершено');
}Якщо поставити await перед кожним запитом, вони виконаються по черзі, а не паралельно.
Як await працює в Event Loop
Коли рушій зустрічає await promise, він:
- призупиняє виконання поточної
async-функції; - реєструє продовження (решту коду функції) як мікрозадачу;
- звільняє основний потік, інший код може виконуватися;
- коли проміс завершується, мікрозадача запускає решту коду функції.
Тому await не «блокує» JS, він просто відкладає продовження функції до готовності проміса.
Приклад 5, «пауза» без блокування
async function wait() {
console.log('Початок');
await new Promise(res => setTimeout(res, 2000));
console.log('Кінець');
}
wait();
console.log('Цей код виконується, поки триває очікування!');Вивід:
Початок
Цей код виконується, поки триває очікування!
(через 2 секунди)
Кінецьawait не блокує потік, лише саму функцію.
Підсумок
Уявіть, що
await- це пауза на світлофорі:
- горить червоне (
Promise pending), ви чекаєте;- зелене (
fulfilled), ви їдете далі;- аварія (
rejected), викидається помилка, і ви переходите вcatch.
| Особливість | Опис |
|---|---|
| Що робить | призупиняє async-функцію, доки проміс не завершиться |
| Повертає | результат resolve або викидає помилку при reject |
| Де можна використовувати | тільки всередині async-функцій (або top-level await у модулях) |
| Не блокує | решта коду програми продовжує виконуватися |
| Працює з | промісами і звичайними значеннями (Promise.resolve(value)) |
Типові помилки
- Вважати, що
awaitблокує сторінку. Він зупиняє лише свою функцію, а не потік: таймери, обробники подій і решта коду працюють далі. awaitу циклі для незалежних запитів. Кожна ітерація чекає на попередню; для незалежних операцій берітьPromise.all.- Не обгортати
awaitуtry...catch. Відхилений проміс кидає виняток, і без обробки він стає unhandled rejection. awaitпозаasync-функцією у звичайному скрипті: це SyntaxError. Top-level await доступний лише в модулях.- Ставити
awaitперед кожнимfetch, коли запити незалежні: так ви навмисно робите код повільнішим.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.