co

generator async control flow goodness

co

![Gitter](https://badges.gitter.im/Join Chat.svg)

Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way.

co@4.0.0 has been released, which now relies on promises. It is a stepping stone towards ES7 async/await. The primary API change is how co() is invoked. Before, co returned a "thunk", which you then called with a callback and optional arguments. Now, co() returns a promise.

co(function* () {
  var result = yield Promise.resolve(true);
  return result;
}).then(function (value) {
  console.log(value);
}, function (err) {
  console.error(err.stack);
});

If you want to convert a co-generator-function into a regular function that returns a promise, you now use co.wrap(fn*).

var fn = co.wrap(function* (val) {
  return yield Promise.resolve(val);
});
 
fn(true).then(function (val) {
 
});

co@4+ requires a Promise implementation. For versions of node < 0.11 and for many older browsers, you should/must include your own Promise polyfill.

When using node 0.11.x or greater, you must use the --harmony-generators flag or just --harmony to get access to generators.

When using node 0.10.x and lower or browsers without generator support, you must use gnode and/or regenerator.

io.js is supported out of the box, you can use co without flags or polyfills.

$ npm install co

Any library that returns promises work well with co.

  • mz - wrap all of node's code libraries as promises.

View the wiki for more libraries.

var co = require('co');
 
co(function *(){
  // yield any promise 
  var result = yield Promise.resolve(true);
}).catch(onerror);
 
co(function *(){
  // resolve multiple promises in parallel 
  var a = Promise.resolve(1);
  var b = Promise.resolve(2);
  var c = Promise.resolve(3);
  var res = yield [a, b, c];
  console.log(res);
  // => [1, 2, 3] 
}).catch(onerror);
 
// errors can be try/catched 
co(function *(){
  try {
    yield Promise.reject(new Error('boom'));
  } catch (err) {
    console.error(err.message); // "boom" 
 }
}).catch(onerror);
 
function onerror(err) {
  // log any uncaught errors 
  // co will not throw any errors you do not handle!!! 
  // HANDLE ALL YOUR ERRORS!!! 
  console.error(err.stack);
}

The yieldable objects currently supported are:

  • promises
  • thunks (functions)
  • array (parallel execution)
  • objects (parallel execution)
  • generators (delegation)
  • generator functions (delegation)

Nested yieldables are supported, meaning you can nest promises within objects within arrays, and so on!

Read more on promises!

Thunks are functions that only have a single argument, a callback. Thunk support only remains for backwards compatibility and may be removed in future versions of co.

yielding an array will resolve all the yieldables in parallel.

co(function* () {
  var res = yield [
    Promise.resolve(1),
    Promise.resolve(2),
    Promise.resolve(3),
  ];
  console.log(res); // => [1, 2, 3] 
}).catch(onerror);

Just like arrays, objects resolve all yieldables in parallel.

co(function* () {
  var res = yield {
    1: Promise.resolve(1),
    2: Promise.resolve(2),
  };
  console.log(res); // => { 1: 1, 2: 2 } 
}).catch(onerror);

Any generator or generator function you can pass into co can be yielded as well. This should generally be avoided as we should be moving towards spec-compliant Promises instead.

Returns a promise that resolves a generator, generator function, or any function that returns a generator.

co(function* () {
  return yield Promise.resolve(true);
}).then(function (val) {
  console.log(val);
}, function (err) {
  console.error(err.stack);
});

Convert a generator into a regular function that returns a Promise.

var fn = co.wrap(function* (val) {
  return yield Promise.resolve(val);
});
 
fn(true).then(function (val) {
 
});

MIT