The main issue I have with "escaping from callback hell" is that it's a half-truth. Although I don't know much about how the Reactive Framework created by Microsoft works, I know they went well beyond the basics to try to make it all-encompassing coming closer to making it a full-truth.<p>Just transmitting data back and forth may play well to the strengths of your abstraction. But we have other uses with Timers that should also need such abstractions.<p>With Timers I have other needs like delaying the execution, resetting the delay countdown, stopping it before it executes it at all (like cancelling it), and finally with an Animation class I needed a way to finish executing a string of events in an instant in order to start a new animation. Also the Animation had other Animation versions at play that could need to be sped up before a new Animation started.<p>In .NET they seem to have a handy feature that waits the code to run before proceeding that comes into play with their .NET version of the Reactive Framework.<p>As far as I can tell, it's tough to really solve it. JavaScript doesn't have extra features like .NET does. We are more limited in what we can do. In Dart they have a version of this called Future that has been streamlined recently. As simple as it may seem to be, it comes with other related abstractions called Streams that altogether make it a bit daunting to escape from that hell only to land on the fire outright.