@KitRedgrave async / await makes this a bit better in javascript
BUT STILL
the right answer is to have coroutines (ideally by delimited continuations) in a way that's much more cleanly baked into the language
Racket / Guile do this in a sane way. async stuff can be made completely clean and look like everyday straightahead coding.
Every time I program in javascript I get so angry because of this.