As we look forward to the ES7
async function, let's take a moment to remember an aging former star that still has a little bit of life left in it: Async.js
Nowadays there are a number of ways to avoid callback hell:
- Transpiler, ES6/7 native promises and native
async. This is doubtless the best choice if you can use it.
- Promise library, probably BlueBird or Q
- Promises combined with Co for flow control
- Async.js or Highland.js by Caolan McMahon (yes, the guy who wrote Async)
Let's leave Highland.js aside for now; we'll return to it in a future post. Promises are now the standard way how to deal with asynchronous code. Is there still any reason to use Async instead? Despite the current primacy of promises, it does retain a couple of advantages:
- It is based on callbacks so integration with existing Node libraries (which are usually based on callbacks) is more seamless. This will likely change now that promises are a standard part of the language, but for now it's nice to not have to worry about promisification.
- It has rich control flow functions like
Flow control in particular is so useful that a port of the Async API exists for both of the major promise libraries: async-q and async-bluebird. This offers the best of both worlds, as you can benefit from Async flow control and still use standard, more versatile promises.