IMHO callback hell is only called hell because of the syntax. So the solution admired here is mostly the do notation, not monads themselves. (But it’s a great feature that the do notation can be used for a general class of problems represented by monads, not a particular one as await, for example.)