I really like JS and it has excellent closure support, but it's really obvious that heavy async programming like we're doing nowadays with AJAX is not what it was designed for.<p>The 'nested callback' problem is one I've encountered over and over. I've figured out a relatively nice way to work around it. The solution goes something like this.<p>- Take the individual actions that you want and put them in closures.<p>- These closures take 1 argument, which is always a callback function that takes no arguments (this is the convention you structure everything around)<p>- Put these closures in an array, in the order that you want them executed<p>- Pass the array to a function that executes them for you (in Haskell it's called a sequence)<p>I have a really quick and really dirty presentation about it here, <a href="http://www.moondust.dds.nl/text/async-presentation/" rel="nofollow">http://www.moondust.dds.nl/text/async-presentation/</a><p>Some code on github up here, <a href="https://github.com/michiel/asynchelper-js" rel="nofollow">https://github.com/michiel/asynchelper-js</a> - the sequencer.js function is verbose, if you read the next SO link I've included a three line example of implementing it.<p>And a stackoverflow answer using this code and some explanation here, <a href="http://stackoverflow.com/questions/4462605/jquery-ajax-each-callback-next-each-firing-before-ajax-completed/4462955#4462955" rel="nofollow">http://stackoverflow.com/questions/4462605/jquery-ajax-each-...</a><p>And another one as a gist on github here, <a href="https://gist.github.com/604730" rel="nofollow">https://gist.github.com/604730</a> (for rendering a massive table from JSON data).<p>There's a lot more to this sequencer pattern. You can nest sequences, you can have the sequencer run each callback using setTimeout(callback, 0) to release control back to the main loop and get out of 'script is doing too much' popups, etc.<p>Need to make an async call? Make a closure that performs the async call and invoke the callback argument in your async callback.<p>Need to add some random JS code to a sequence? Wrap it in a closure and call the callback when you're done. If the random JS code requires an async call, see the previous paragraph.<p>Error handling, of course, is still awful. You can extend the sequencer convention to add error closures as a second parameter, you can do everything inside the closures in try/catch blocks and finally always call the callback, etc. But that just tends to make a mess of things. So the examples just assume everything is going fine.<p>It's not an ideal solution, but it's native JS and works <i>everywhere</i>.<p>It allows you to structure your code into functional blocks and work on them separately instead of making everything one big nested callback mess.