Що буде, якщо не поставити await
Якщо не поставити await, то замість результату ви отримаєте сам Promise: обіцянку, яка колись виконається, але ще не виконана. Без await ви не «чекаєте» на результат, а просто створюєте проміс і йдете далі.
Теорія
TL;DR
- Виклик
async-функції безawaitповертаєPromise, а не значення. - Виконання не призупиняється: код одразу йде далі, а функція працює у фоні.
- Звернення до поля результату (
user.name) даєundefined, це помилка логіки, а не синтаксису. try...catchне спіймаєreject, якщо ви не поставилиawait.- Іноді пропустити
awaitправильно: так задачі стартують паралельно, а чекають їх черезPromise.all. return await promiseу звичайномуreturnнадлишковий,asyncі так загортає результат.
Швидкий приклад
async function getData() {
return 'Дані';
}
async function main() {
const withoutAwait = getData(); // Promise { 'Дані' }
const withAwait = await getData(); // 'Дані'
console.log(withoutAwait, withAwait);
}
main();Без await у змінній опиняється проміс
Приклад 1, без await повертається проміс
async function getData() {
return 'Дані';
}
async function main() {
const result = getData(); // без await
console.log(result);
}
main();Вивід:
Promise { 'Дані' }Чому:
getData(), цеasync-функція, вона завжди повертає проміс;- без
awaitви отримуєте об’єкт Promise, а не'Дані'.
Приклад 2, з await
async function main() {
const result = await getData(); // дочекалися
console.log(result);
}
main();Вивід:
Даніawait «розгортає» проміс і повертає його значення.
Код іде далі, не чекаючи
Приклад 3, не поставили await, і код пішов далі
async function delay() {
await new Promise(res => setTimeout(res, 2000));
console.log('Виконано через 2 секунди');
}
async function run() {
delay(); // не чекаємо!
console.log('Продовжуємо далі');
}
run();Вивід:
Продовжуємо далі
Виконано через 2 секундиБез await виконання не призупиняється: функція delay() запущена у фоні, а програма йде далі.
Приклад 4, через відсутність await результат не той
async function fetchUser() {
return { name: 'Alex' };
}
async function showUser() {
const user = fetchUser(); // забули await
console.log('Ім’я користувача:', user.name);
}
showUser();Вивід:
Ім’я користувача: undefinedТому що user, це не об’єкт, а Promise, у якого немає поля name. Тобто це помилка логіки, а не синтаксису.
Коли await не ставлять навмисно
Приклад 5, паралельні задачі. Іноді не ставити await правильно, якщо ви хочете запустити операції паралельно:
async function load() {
const userPromise = fetch('/api/user');
const postsPromise = fetch('/api/posts');
// чекаємо на обидві паралельно
const [user, posts] = await Promise.all([userPromise, postsPromise]);
console.log('Обидві відповіді отримано');
}Якби ви поставили await одразу після кожного fetch, вони виконувалися б по черзі, а не одночасно.
Приклад 6, без await під час повернення
async function foo() {
return await Promise.resolve('OK');
}await тут надлишковий, можна просто:
async function foo() {
return Promise.resolve('OK');
}Тому що async-функція все одно загортає результат у проміс.
Під капотом: що реально відбувається
Коли ви викликаєте async-функцію:
const p = myAsyncFunction();JavaScript негайно повертає об’єкт Promise, а код усередині починає виконуватися асинхронно. Якщо не поставити await, цей проміс просто залишиться «у повітрі», і результат його виконання ви ніколи не використаєте.
Поширені проблеми без await
| Помилка | Що відбувається |
|---|---|
Забули await під час виклику async-функції | У змінній опиняється Promise, а не результат |
Повернення без await всередині іншої async | Може повернути «незавершений» проміс |
| Неузгодженість даних | Код іде далі, поки проміс ще не виконався |
| Помилки не ловляться | try...catch не спіймає reject, якщо ви не дочекалися через await |
Уявіть, що
await, це «зачекати на замовлення»:
- з
await: ви стоїте біля стійки, чекаєте на каву і отримуєте чашку;- без
await: ви просто зробили замовлення і пішли далі, каву приготують, але ви її не забрали.
| Сценарій | Що станеться |
|---|---|
Не поставили await | Функція поверне Promise, виконання продовжиться одразу |
Поставили await | Виконання призупиниться, доки проміс не завершиться |
Помилка без await | try...catch не спіймає, бо на проміс не чекали |
Коли не ставити await | Під час запуску паралельних задач (Promise.all) |
Типові помилки
- Звертатися до полів результату без
await.user.nameна промісі завждиundefined, і жодної помилки ви не побачите. - Розраховувати на
try...catchбезawait. Блок завершиться раніше, ніж проміс відхилиться, і ви отримаєте unhandled rejection. - Забувати
awaitуreturnвсерединіtry. Помилку спіймає не локальнийcatch, а викликач. - Ставити
awaitперед кожним незалежним запитом. Паралельні операції варто запускати безawaitі збирати черезPromise.all. - Вважати, що без
awaitфункція не запускається. Вона запускається одразу, просто ніхто не чекає на її результат.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.