Що повертає async-функція?
Коротка відповідь
async-функція завжди повертає Promise,
незалежно від того, що ти всередині неї повертаєш.
Приклад 1 - звичайне значення
async function foo() {
return 42;
}
const result = foo();
console.log(result);Вивід:
Promise { 42 }Навіть якщо ти повертаєш звичайне число,
воно автоматично обгортається в Promise.resolve(42).
Тобто це те саме, що:
function foo() {
return Promise.resolve(42);
}Приклад 2 - явний Promise всередині
async function bar() {
return Promise.resolve('OK');
}
bar().then(console.log); // OKЯкщо всередині повернути вже готовий Promise,
він не обгортається вдруге,
а просто "прокидається" назовні.
Приклад 3 - помилка (throw) перетворюється на reject
async function fail() {
throw new Error('Помилка!');
}
fail().catch(err => console.error(err.message));Вивід:
Помилка!Якщо всередині async-функції відбувається throw,
то проміс, який повертається, переходить у стан rejected
(наче викликали Promise.reject(err)).
Приклад 4 - з await
async function getData() {
const value = await Promise.resolve('Успішно');
return value;
}
getData().then(console.log);Вивід:
УспішноТут await просто чекає на виконання проміса,
а результат функції, як і раніше, - Promise, який "резолвиться" у 'Успішно'.
Під капотом
Коли JS бачить async function foo(), він робить приблизно таке:
function foo() {
return new Promise((resolve, reject) => {
try {
// тіло функції
const result = ...;
resolve(result);
} catch (err) {
reject(err);
}
});
}Тобто:
- будь-яке
returnперетворюється наresolve(value); - будь-яке
throwперетворюється наreject(error).
Приклад 5 - що саме повертає виклик
async function demo() {
return 'Hello';
}
const p = demo();
console.log(p instanceof Promise); // true
p.then(console.log); // HelloПриклад 6 - ланцюжок async-функцій
async function a() {
return 10;
}
async function b() {
const x = await a();
return x * 2;
}
b().then(console.log); // 20Обидві функції повертають Promise,
тому await a() чекає, поки проміс з a() зарезолвиться.
Проста аналогія
async-функція - це як лист з відстеженням: ти не отримуєш результат одразу, ти отримуєш обіцянку, що результат буде доставлено пізніше (Promise).
Підсумок
| Всередині функції | Що повертає async-функція |
|---|---|
return 123 | Promise.resolve(123) |
return Promise.resolve('OK') | Promise.resolve('OK') (без обгортки) |
throw new Error('fail') | Promise.reject(Error('fail')) |
await expr | чекає expr, потім повертає результат як resolve |
Тобто результат завжди проміс,
і лише всередині async можна писати "звичайний" асинхронний код з await.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.