Harmony Generators
Now that generators have finally landed in V8 and thus in Node.js, under a flag (--harmony or --harmony-generators). These greatly reduce the amount of callback hell you have. It makes writing asynchronous code truly great.
The best way to utilize generators is to employ some sort of control-flow library. This will enable to flow to continue going as you yield within generators.
Recap/Overview:
If you're unfamiliar with generators, they're a practice of pausing the execution of special functions (called generators). This practice is called yielding using the yield keyword.
Example:
function* someGenerator() {
yield []; // Pause the function and pass an empty array.
}
Thus, whenever you call this function the first time, it'll return a new generator instance. This allows you to call next() on that object to start or resume the generator.
var gen = someGenerator();
gen.next(); // { value: Array[0], done: false }
You would keep calling next until done returns true. This means the generator has completely finished it's execution, and there are no more yield statements.
Control-Flow:
As you can see, controlling generators are not automatic. You need to manually continue each one. That's why control-flow libraries like co are used.
Example:
var co = require('co');
co(function*() {
yield query();
yield query2();
yield query3();
render();
});
This allows the possibility to write everything in Node (and the browser with Facebook's Regenerator which takes, as input, source code that utilize harmony generators and splits out fully compatible ES5 code) with a synchronous style.
Generators are still pretty new, and thus requires Node.js >=v11.2. As I'm writing this, v0.11.x is still unstable and thus many native modules are broken and will be until v0.12, where the native API will calm down.