There are plenty of occasions where retuning a promise is a good thing. I am often saddened to see how much "await"ing is done which could be avoided. Otherwise you are just turning asynchronous into synchronous.
It is very much not being turned into synchronous code. There are a lot of reasons to use async code, and they're all still valid with this pattern.
For example:
- the event loop is still not being blocked
- the calling code can still be flat instead of nested callbacks (truly synchronous) or chained `.then` calls
Is it a little bit more boilerplate? Yes, definitely, and it's certainly less nice to look at. But it's linter-enforceable consistency that removes the cognitive overhead of an annoying to debug footgun.
Note: My favorite style is typed error returns instead of thrown exceptions. In that world, you only need try/catches at the boundaries of your code and for application crashing exceptions. Unfortunately most codebases aren't written like that and I'm often working in inherited code instead of greenfield.
I think my point is that awaits are often used because the coder can't work out or can't be bothered to work out how to treat promises more intelligently.
Important to note that unless the inner function throws an exception, the two versions are essentially identical, even sharing (if using typescript) a return type definition of `Promise<ReturnType<InnerFunction>>`.
That's because `await` flattens nested promises, so both `Awaited<Promise<T>>` and `Awaited<Promise<Promise<Promise<T>>>>` resolve to `T`.
Worth noting that this is easily enforceable with eslint: https://typescript-eslint.io/rules/return-await/
reply