function * HelloGen(){
yield 100;
yield 400;
}
var gen = HelloGen();
console.log(gen.next()); // {value: 100, done: false}
console.log(gen.next()); // {value: 400, done: false}
console.log(gen.next()); // {value: undefined, done: true}
`</pre>
<pre>`function * HelloGen2() {
var a = yield 100;
var b = yield a + 100;
console.log(b);
}
var gen2 = HelloGen2();
console.log(gen2.next()); // {value: 100, done: false}
console.log(gen2.nect(500)); // {value: 600, done: false}
console.log(gen2.next(1000)); // {value: undefined, done: done}
// prints 1000
`</pre>
### Preventing Callback Hell
So, how can generators be used to avoid callback hell? First, you need to understand a simple technique that we will be using heavily with generators to write code without callbacks.
#### Understanding Thunks
A thunk is a partially evaluated function which accepts a single callback as the argument. Within generators, we'll be yielding thunks to write without callbacks. A simple thunk is shown below.
<pre>`function(callback) {
fs.readFile('myfile.md', 'utf8', callback)
}
`</pre>
Thunks can also be created dynamically as shown below:
<pre>`function readFile(filename) {
return function(callback) {
fs.readFile(filename, 'utf8', callback);
};
}
`</pre>
#### Using `co`
`co` is a nice module which helps to use thunks and generators together to create Node.js applications without callbacks.
A simple application which uses `co` and the `readFile()` thunk.
<pre>`var co = require('co');
co(function* (){
var file1 = yield readFile('file1.md');
var file2 = yield readFile('file2.md');
console.log(file1);
console.log(file2);
})();
`</pre>
As you can see, we are no longer using callbacks. This gives us a simple way to write large modular Node apps easily.
###### How `co` Works Internally
First, it calls
next(null)
and gets a thunk.Then, it evaluate the thunk and saves the result.
Then, it calls
next(savedResult)
(in this case, saveResult == readFile(‘file1.md’), and next(savedResult) pass the content to var file1)Repeat these steps until
next()
return{done: true}
A minimal version of
co
written to show how it works internally.1
2
3
4
5
6
7
8
9function co(generator){
var gen = generator();
function nextItem(err, result) {
var item = gen.next(result);
<pre>`if (!item.done) {
item.value(nextItem); // item.value is a thunk, because yield a thunk
}
}
nextItem();
}