gene

A generator-based control-flow library.

npm install gene
2 downloads in the last week
6 downloads in the last month

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'));  // <-- await!
  yield fs.readFile('/path/to/file2', 'utf8', g.cb('d2'));  // <-- await!
  yield fs.readFile('/path/to/file3', 'utf8', g.cb('d3'));  // <-- await!

  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;    // <-- await!

  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) {
    // handle error
  }
})();

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; // junp to callback

  // not run here.

})(function(err, data) {
  // always run
});

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) {
  // do something

  yield setTimeout(g.cb(), 100); // wait 100ms

  // do something

  yield setTimeout(g.cb(), 200); // wait 200ms

  // do something
})();

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; // wait 100ms

  var str = g.data.d1 + g.data.d2;
  console.log(str);   // abcd
})();

License

MIT

npm loves you