Skip to main content

What does an async function return?

Short answer

An async function always returns a Promise, no matter what you return inside it.

Example 1 - a plain value

javascript
async function foo() { return 42; } const result = foo(); console.log(result);

Output:

javascript
Promise { 42 }

Even if you return a plain number, it is automatically wrapped in Promise.resolve(42).

In other words, it is the same as:

javascript
function foo() { return Promise.resolve(42); }

Example 2 - an explicit Promise inside

javascript
async function bar() { return Promise.resolve('OK'); } bar().then(console.log); // OK

If you return an already-created Promise inside, it is not wrapped a second time - it is simply passed through.

Example 3 - an error (throw) turns into a reject

javascript
async function fail() { throw new Error('Error!'); } fail().catch(err => console.error(err.message));

Output:

javascript
Error!

If a throw happens inside an async function, the returned promise transitions to the rejected state (as if Promise.reject(err) had been called).

Example 4 - with await

javascript
async function getData() { const value = await Promise.resolve('Success'); return value; } getData().then(console.log);

Output:

javascript
Success

Here await simply waits for the promise to settle, while the function's result is still a Promise, which resolves to 'Success'.

Under the hood

When JS sees async function foo(), it does roughly the following:

javascript
function foo() { return new Promise((resolve, reject) => { try { // function body const result = ...; resolve(result); } catch (err) { reject(err); } }); }

That is:

  • any return turns into resolve(value);
  • any throw turns into reject(error).

Example 5 - what the call actually returns

javascript
async function demo() { return 'Hello'; } const p = demo(); console.log(p instanceof Promise); // true p.then(console.log); // Hello

Example 6 - a chain of async functions

javascript
async function a() { return 10; } async function b() { const x = await a(); return x * 2; } b().then(console.log); // 20

Both functions return a Promise, so await a() waits for the promise from a() to resolve.

Simple analogy

An async function is like a tracked letter: you don't get the result right away, you get a promise that the result will be delivered later (Promise).

Summary

Inside the functionWhat the async function returns
return 123Promise.resolve(123)
return Promise.resolve('OK')Promise.resolve('OK') (no wrapper)
throw new Error('fail')Promise.reject(Error('fail'))
await exprwaits for expr, then returns the result via resolve

So the result is always a promise, and only inside async can you write "regular"-looking asynchronous code with await.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.