Home > Blockchain >  Should I define async function if I explicitly return a Promise?
Should I define async function if I explicitly return a Promise?

Time:10-23

We know that async functions return a Promise implicitly. But I have a purely pedantic question. Should I put an async keyword if I return a Promise explicitly?

Is this:

const wait = async ms => new Promise(
    resolve => setTimeout(resolve, ms)
);

Any different than this?

const wait = ms => new Promise(
    resolve => setTimeout(resolve, ms)
);

I believe that technically they are identical. Is there any style guide or official recommendation behind any of these two ways to define this kind of function?

CodePudding user response:

There are three main reasons I think about for using async functions:

  1. You want to use await.
  2. You want it to automatically catch synchronous exceptions and turn them into a rejected promise.
  3. You want it to always return a promise, regardless of what your function actually returns.

So, if you aren't using await and you don't need point #2 and you are manually returning a promise already, then there's really no reason/advantage to declaring the function as async.


A few more thoughts on the three points above.

Point #1 requires async if you're going to use await. There is no other way around it.

Points #2 and #3 are really just programming conveniences. If you either catch your own synchronous exceptions or are sure there are no synchronous exceptions and you are controlling all code paths to return a promise, then async is not necessary.

Both points #2 and #3 can arise if your code has both a synchronous code path and an asynchronous code path, such as checking a cache and returning a value if its present in the cache and, if not in the cache, then make a network request to fetch the value. As described above, this can be coded manually without async, but the code can sometimes be a little simpler with async because it will automaticlly catch your synchronous exceptions and automatically wrap a return value in a promise.

CodePudding user response:

In the given example the async keyword is essentially only wrapping the return value in Promise.resolve(). See the async function documentation.

So on one hand you have:

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

While on the other you have:

const wait = async ms => new Promise(resolve => setTimeout(resolve, ms));
// is similar to
const wait = ms => Promise.resolve(new Promise(resolve => setTimeout(resolve, ms)));

They are essentially the same and I would personally go for the variant without the async keyword.

Note:

Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve, they are not equivalent.

An async function will return a different reference, whereas Promise.resolve returns the same reference if the given value is a promise.

It can be a problem when you want to check the equality of a promise and a return value of an async function.

const p = new Promise((res, rej) => {
  res(1);
})

async function asyncReturn() {
  return p;
}

function basicReturn() {
  return Promise.resolve(p);
}

console.log(p === basicReturn()); // true
console.log(p === asyncReturn()); // false
  • Related