gene
A generator-based control-flow library for Node.js.
Easily parallel execute and error handling.
Installation
Node version >= v0.11.4
$ npm install gene
Usage
If Node.js is v0.11.x, you must use the --harmony-generators
flag.
$ node --harmony-generators your-script.js
Example
Serial
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
yield fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
yield fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
yield fs.readFile('/path/to/file3', 'utf8', g.cb('d3'));
var str = g.data.d1 + g.data.d2 + g.data.d3;
console.log(str);
})();
Parallel
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
fs.readFile('/path/to/file3', 'utf8', g.cb('d3'));
yield 0;
var str = g.data.d1 + g.data.d2 + g.data.d3;
console.log(str);
})();
Error handling
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
try {
fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
yield 0;
} catch(e) {
}
})();
Callback
sample() is called at the end.
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
yield 0;
})(sample);
function sample(err, data){
if (err) throw err;
console.log(data.d1 + data.d2);
}
Jump to callback
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
yield fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
if (true) return;
})(function(err, data) {
});
Nesting
var fs = require('fs');
var gene = require('gene');
gene(function*(g) {
fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
yield 0;
fs.readFile('/path/to/file3', 'utf8', g.cb('d3'));
yield 0;
gene(function*(g) {
fs.readFile('/path/to/file4', 'utf8', g.cb('e1'));
fs.readFile('/path/to/file5', 'utf8', g.cb('e2'));
yield 0;
fs.readFile('/path/to/file6', 'utf8', g.cb('e3'));
yield 0;
})(g.cb('d4'));
yield 0;
var str = g.data.d1 + g.data.d2 + g.data.d3 +
g.data.d4.e1 + g.data.d4.e2 + g.data.d4.e3;
console.log(str);
})();
Delegating yield
var gene = require('gene');
function* sub(g) {
fs.readFile('/path/to/file1', 'utf8', g.cb('d1'));
fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));
yield 0;
}
gene(function*(g) {
yield* sub(g);
fs.readFile('/path/to/file3', 'utf8', g.cb('d3'));
fs.readFile('/path/to/file4', 'utf8', g.cb('d4'));
yield 0;
var str = g.data.d1 + g.data.d2 + g.data.d3 + g.data.d4;
console.log(str);
})();
setTimeout
simply
var gene = require('gene');
gene(function*(g) {
yield setTimeout(g.cb(), 100);
yield setTimeout(g.cb(), 200);
})();
parallel
var gene = require('gene');
gene(function*(g) {
var cb1 = g.cb('d1');
setTimeout(function() {
try {
cb1(null, 'ab');
} catch (e) {
cb1(e);
}
}, 100);
var cb2 = g.cb('d2');
setTimeout(function() {
try {
cb2(null, 'cd');
} catch (e) {
cb2(e);
}
}, 50);
yield 0;
var str = g.data.d1 + g.data.d2;
console.log(str);
})();
License
MIT