Skip to content

Instantly share code, notes, and snippets.

@fengmk2
Created March 13, 2014 01:45
Show Gist options
  • Select an option

  • Save fengmk2/9520498 to your computer and use it in GitHub Desktop.

Select an option

Save fengmk2/9520498 to your computer and use it in GitHub Desktop.
co very nice to mocha
describe('example of co work with mocha', function () {
it('should work', co(function *() {
var result = yield *urllib.request('http://cnpmjs.org', {dataType: 'json'});
result.should.have.keys('data', 'status', 'headers');
result.status.should.equal(200);
result.data.should.be.an.Object;
result.headers['content-type'].should.equal('application/json');
}));
});
// `co(function *() {});` will return a thunk: `function (done) {};`
@fengmk2

fengmk2 commented Mar 13, 2014

Copy link
Copy Markdown
Author

console.log(co(function *() {}));

  function (done) {
    var ctx = this;

    // in toThunk() below we invoke co()
    // with a generator, so optimize for
    // this case
    var gen = fn;

    // we only need to parse the arguments
    // if gen is a generator function.
    if (isGenFun) {
      var args = slice.call(arguments), len = args.length;
      var hasCallback = len && 'function' == typeof args[len - 1];
      done = hasCallback ? args.pop() : error;
      gen = fn.apply(this, args);
    } else {
      done = done || error;
    }

    next();

    function next(err, res) {
      var ret;

      // multiple args
      if (arguments.length > 2) res = slice.call(arguments, 1);

      // error
      if (err) {
        try {
          ret = gen.throw(err);
        } catch (e) {
          return done(e);
        }
      }

      // ok
      if (!err) {
        try {
          ret = gen.next(res);
        } catch (e) {
          return done(e);
        }
      }

      // done
      if (ret.done) return done(null, ret.value);

      // normalize
      ret.value = toThunk(ret.value, ctx);

      // run
      if ('function' == typeof ret.value) {
        var called = false;
        try {
          ret.value.call(ctx, function(){
            if (called) return;
            called = true;
            next.apply(ctx, arguments);
          });
        } catch (e) {
          setImmediate(function(){
            if (called) return;
            called = true;
            next(e);
          });
        }
        return;
      }

      // invalid
      next(new Error('yield a function, promise, generator, array, or object'));
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment