Skip to main content

Що робить await

await - це оператор, який призупиняє виконання async-функції, доки проміс не виконається (fulfilled) або не буде відхилений (rejected). Після цього await або повертає результат проміса, або викидає помилку, як звичайний throw.

Теорія

TL;DR

  • await чекає на завершення проміса всередині async-функції.
  • Якщо проміс виконано успішно, await повертає його результат.
  • Якщо проміс відхилено, await викидає помилку, і її ловить try...catch.
  • Працює тільки всередині async-функцій або як top-level await у модулях.
  • Не блокує потік: інший код продовжує виконуватися, поки функція «стоїть на паузі».
  • Зі звичайним значенням теж працює: воно загортається в Promise.resolve(value).

Швидкий приклад

javascript
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

javascript
let result = await promise;

Працює тільки всередині async-функцій (або в top-level await у модулях).

Приклад 1, очікування проміса

javascript
async function example() { console.log('Перед await'); const result = await Promise.resolve('Готово'); console.log('Після await:', result); } example();

Вивід:

text
Перед await Після await: Готово

await чекає на виконання проміса і повертає 'Готово'.

Приклад 6, зі значеннями, що не є промісами. Якщо передати звичайне значення, воно негайно загортається в Promise.resolve():

javascript
async function demo() { const result = await 42; console.log(result); } demo(); // 42

Це потрібно для уніфікації: await завжди працює так, ніби перед ним проміс.

Приклад 7, вкладені await

javascript
async function inner() { return 'Всередині'; } async function outer() { const res = await inner(); console.log('Результат:', res); } outer();

Вивід:

text
Результат: Всередині

Оскільки inner() повертає проміс, await просто чекає на його завершення.

Помилка: reject перетворюється на виняток

Приклад 2, помилка через await

javascript
async function fail() { try { const res = await Promise.reject('Помилка!'); } catch (err) { console.error('Спіймали:', err); } } fail();

Вивід:

text
Спіймали: Помилка!

Якщо проміс відхилено, await кидає виняток, тому помилки зручно ловити через try...catch.

Послідовно чи паралельно

Приклад 3, послідовне виконання

javascript
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();

Вивід:

text
1 (через 1 секунду) 2 (через 1 секунду) 3

Кожен await чекає на завершення попереднього проміса, тому код працює послідовно.

Приклад 4, паралельне виконання (без await одразу)

javascript
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, він:

  1. призупиняє виконання поточної async-функції;
  2. реєструє продовження (решту коду функції) як мікрозадачу;
  3. звільняє основний потік, інший код може виконуватися;
  4. коли проміс завершується, мікрозадача запускає решту коду функції.

Тому await не «блокує» JS, він просто відкладає продовження функції до готовності проміса.

Приклад 5, «пауза» без блокування

javascript
async function wait() { console.log('Початок'); await new Promise(res => setTimeout(res, 2000)); console.log('Кінець'); } wait(); console.log('Цей код виконується, поки триває очікування!');

Вивід:

text
Початок Цей код виконується, поки триває очікування! (через 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, коли запити незалежні: так ви навмисно робите код повільнішим.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.