JavaScript also has the benefit of a single threaded event loop - that eliminates a whole class of complexity and dealing with schedulers etc. - there is only one.
Async already gets messier in C# for example which also has a GC.
This is a nice read on why you likely should prefer a single threaded runtime and enable parallelism through other means. Or decide to pay the synchronization cost.
if you write harder concurrent program in JS, single threaded event loop does not help. It still has also same concurrency problems.
e.g. if there is shared global mutable state:
a) in workflow 1 you have, do_some_work_on_global_state; do some IO; in IO callback, finish more do_some_work_on_global_state.
b) in workflow 2 .. same like above work on global_state.
Now, in IO callback, you don't know if workflow 2 ran and have to handle all possible combinations of global_state above.
Replace global_state with common_state and problem still remains.
If you don't have common_state between multiple workflows, then it is not a hard concurrency problem and should be easy to do in all languages.
Sure it does, you don't have to manage on which thread you handle continuations (which you must in multithreaded GUI for example) - there's only one scheduler which simplifies the async API a lot.
But even for concurrency - single threaded event loop/cooperative multitasking eliminates a whole class of partial state updates and synchronization primitive/locking errors - it's not even close to preemptive multitasking complexity.
Async already gets messier in C# for example which also has a GC.