There are four main reasons I think about for using async
functions:
- You want to use
await
.
- You want it to automatically catch synchronous exceptions and turn them into a rejected promise.
- You want it to always return a promise, regardless of what your function actually returns.
- You like the fact that making the function
async
makes it clear to callers looking at the code that the function always returns a promise - essentially self documenting.
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 requirement to declaring the function as async
.
A few more thoughts on the 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.
Point #4 is just a coding style preference. If you like the "self-documenting" aspects of making the function async
, you can do that as an indication that it always returns a promise.
And, for anyone interested in lots of technical detail about how async
functions work internlly and have been optimized over the years, this is a fairly indepth article on the topic: V8 blog on fast async.