Coroutines (unlike async/await) would allow one to wait on an async result without losing the stack which is waiting. This would avoid the need for (often) inscrutable callback state machines (Javascript's version of GOTOS).
Async/await has a logical stack that is distinct from the physical stack(s). Quality tooling would show you said logical stack instead of a mish-mash of physical stacks from different async functions that happen to be intermingled on the current thread. Example:
So you don't need to deal with "inscrutable callback state machines" anymore so than you need to deal with the assembly labels and jumps that your for-loop compiles into.