- Spring MVC (Java Futures)
- Spring Webflux (Reactor observables)
- Scala (Scala Futures & for comprehensions)
- TS async/await
- Angular observables
- React hooks (which combined with Redux, React Query etc. is a special approach to async programming.)
I think it's very important to understand that ultimately, async (non-blocking) programming is kind of a "hard problem" and there is no trivial solution for it. But we can't get around it because we must not block code execution: Javascript runtime environments are single-threaded (except workers) and the JVM has limited thread count, too.
Any senior developer has to understand how each of these approaches work and how they are trying to solve the issue of non-blocking code execution. I dare say that this problem area is one of the hardest ones during becoming a more senior developer.
In terms of ergonomy (developer experience) when it comes to simple chained non-blocking calls, in my opinion nothing beats async/await in terms of syntax simplicity. I miss them from Java & Scala! No indentation, lambda functions, flatmaps, monads or special methods/hooks needed. You just have the result of an async method right there.
I don't agree with the author that we shouldn't use async/await because it _looks like_ synchronous code. We _should_ use it to keep syntax simple and clean wherever possible!
The developer has to properly learn the language fundamentals (and how JS code execution works) and know that async/await is just syntax sugar over Promises and generator functions. If they don't do this, then having a Promise.then() chain instead of async/await won't help that developer write better code.
On the other hand, once they understand it, they can freely choose between async/await and Promises depending on what needs to be written.