(Don't mean to divert this thread from Kal, but this is on the topic of "callbacks are bad" etc.)
For some time now, I've been accumulating async patterns I've needed when writing JS code in my monadic IO.js library[1]. The aim of IO.js is to provide higher levels of thinking about sequences of actions without worrying about whether they are async, and with a rich set of error management tools (for ex, exceptions are turned into recoverable conditions in IO.js).
The crux of the "callback hell" problem is, contrary to what many have claimed, is not the nesting that results when the callbacks need to be called in temporal order. That much is straightforward to deal with. The "hell" rears its head when you need to coordinate multiple such sequences that are running concurrently. The composable actions you get from a monadic treatment combined with CSP-style channels, are an expressive framework to build abstractions on (tldr - Haskell's implementation is awesome!).
For illustration, the framework in IO.js is flexible enough to implement a node.js web server that can express PG's "Arc challenge" concisely (though that challenge is practically obsolete). Take a look at [2].
For a simpler example, `IO.trace` is a straight forward way to generate a trace dump to console of a sequence of asynchronous actions. You don't need to "enable trace" for an entire app. You can choose to trace only a particular sequence. This is pretty neat when debugging. Stack traces are useless when dealing with async processes anyway.
>The "hell" rears its head when you need to coordinate multiple such sequences that are running concurrently.
This situation is why I wrote DelayedOp: https://github.com/osuushi/DelayedOp . Of all the little reusable code bits I've written, this one has ended up in more of my projects than any other.
Basically, a DelayedOp is a lightweight manager that runs a callback after its "wait" and "ok" calls have balanced. It ends up being equivalent to _.after(), but it's more natural to use than manually counting your concurrent operations, and it has some conveniences for debugging, so that if a callback never fires, you can find out why.
For some time now, I've been accumulating async patterns I've needed when writing JS code in my monadic IO.js library[1]. The aim of IO.js is to provide higher levels of thinking about sequences of actions without worrying about whether they are async, and with a rich set of error management tools (for ex, exceptions are turned into recoverable conditions in IO.js).
The crux of the "callback hell" problem is, contrary to what many have claimed, is not the nesting that results when the callbacks need to be called in temporal order. That much is straightforward to deal with. The "hell" rears its head when you need to coordinate multiple such sequences that are running concurrently. The composable actions you get from a monadic treatment combined with CSP-style channels, are an expressive framework to build abstractions on (tldr - Haskell's implementation is awesome!).
For illustration, the framework in IO.js is flexible enough to implement a node.js web server that can express PG's "Arc challenge" concisely (though that challenge is practically obsolete). Take a look at [2].
For a simpler example, `IO.trace` is a straight forward way to generate a trace dump to console of a sequence of asynchronous actions. You don't need to "enable trace" for an entire app. You can choose to trace only a particular sequence. This is pretty neat when debugging. Stack traces are useless when dealing with async processes anyway.
[1]: https://github.com/srikumarks/IO.js [2]: https://github.com/srikumarks/IO.js/blob/master/examples/arc...