DEV Community

aderchox
aderchox

Posted on • Updated on

Weird thing I missed about Async/Await: Implicit Returns

Weird I didn't know this so far, because I've been using async/await syntax for a while now, but I've just realized this.

Async functions return a Promise implicitly and automatically themselves. We don't need to do anything for this (e.g., we don't need to do return new Promise((resolve)=>{/*...*/}) inside our async functions (unless we explicitly need to)).

Example
This snippet:

async function foo(){
    return "foo";
}
Enter fullscreen mode Exit fullscreen mode

is an equivalent of this snippet:

async function foo(){
    return Promise.resolve("foo");
}
Enter fullscreen mode Exit fullscreen mode

For our comfort, JavaScript does the above conversion itself automatically.
Note that even if we return nothing, still the above conversion will take place, i.e.,:

async function foo(){}
// is an equivalent of:
// async function foo(){ return Promise.resolve(undefined); }

// Let's call foo to confirm our claim:
foo();
// Prints: Promise {<fulfilled>: undefined}
Enter fullscreen mode Exit fullscreen mode

Now why would understanding this be useful? Well personally I knew that whenever we use an await keyword, it has to be kind of *coupled* with some Promise, so for instance we could do:

const delayFoo = ms =>
  new Promise(
    resolve =>
      setTimeout(() => resolve("foo"), ms)
  );
const delayFooThreeSeconds = () => delayFoo(3000); // (*) This returns a Promise explicitly.

// now inside some async function:
async function demo(){
    console.log("foo", 1);
    console.log(await delayFooThreeSeconds(), 2); // (*) This awaits the Promise returned explicitly by the call to delayFooThreeSeconds.
    console.log("foo", 3);
}

demo();
Enter fullscreen mode Exit fullscreen mode

delayFoo is an example of a function that is returning a Promise explicitly, but what if we need an async call within our function at a point that is not where it's returning? For example, consider a nested async/await where a function is both doing an async operation and is supposed to be awaited itself too inside another async function:

async function bar(){ // <-- (*) This function is not returning any Promises explicitly.
  doSomething();
  await delayFooThreeSeconds()
  doSomethingElse();
}
async function baz(){
  await bar(); // <--- (*) Would this be possible?
}
Enter fullscreen mode Exit fullscreen mode

Now the bar function is not returning a Promise explicitly, so could it be awaited inside baz? As you might have guessed the correct answer by now: "Yes", because the above function is returning a Promise implicitly. (Even if we have multiple async calls wrapped inside an async function, the hierarchy of the promises will be the same as the invocations of the async functions.)

Here are some working examples for you to play with and see things better in action: https://playcode.io/928113/


You're also welcome to join our very small and fledging Discord community where we share the things that we learn in the realm of programming with each other, it's called TIL (stands for "Today-I-Learned"). Join here: https : // discord.gg / ATp8gc7G. Thanks for reading this article.

Top comments (0)