co是干啥用的

再说co之前要先搞清楚 Thunk函数和 Generator函数

Generator函数:
function* gen(x){
  var y = yield x + 2;
  return y;
}

var g = gen(1);
g.next() // { value: 3, done: false }
g.next() // { value: undefined, done: true }

简单来说Generator 可以让你拥有函数的控制权。上面代码中gen函数返回一个对象,这个对象中有value 和dong 两个值, value就是 函数中 yield 后面语句的值,而done 则用来判断函数时候执行完。你可以通过next()函数来执行代码,每次调用next 函数都会执行到 yield 并且返回后面语句的值。

Thunk函数:
// 正常版本的readFile(多参数版本)
fs.readFile(fileName, callback);

// Thunk版本的readFile(单参数版本)
var readFileThunk = Thunk(fileName);
readFileThunk(callback);

var Thunk = function (fileName){
  return function (callback){
    return fs.readFile(fileName, callback); 
  };
};

Thunk 可以让你把一个接受多参数的函数(至少要用一个回调函数作为参数)变成 接受单参数的函数。 上面代码中先用 Thunk函数 固定来一个参数 然后返回一个函数。这样,这个函数就只要接受一个回调作为参数。

Generator 跟 Thunk 配合使用 可以实现 Generator 函数自动执行

co是干啥用的

co 可以帮你自动执行Generator

直接看源码:

function co(gen) {
  var ctx = this;

  return new Promise(function(resolve, reject) {
    if (typeof gen === 'function') gen = gen.call(ctx);
    if (!gen || typeof gen.next !== 'function') return resolve(gen);

    onFulfilled();
    function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }    
  });
}

function next(ret) {
  if (ret.done) return resolve(ret.value);
  var value = toPromise.call(ctx, ret.value);
  if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
  return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"'));
    }
});

co 函数接受 Generator 函数作为参数,返回一个 Promise 对象。
然后 在Promise中 需要判断一下 参数是不是Generator 函数,如果是就执行这个函数。这样就会得到一个新的对象,你可以通过这个对象的next 控制Generator 函数的执行,如果不是就返回,并将 Promise 对象的状态改为 resolved 。

onFulfilled 函数会调用上面返回的对象的next函数让Generator 函数进行下一步, onFulfilled 函数中用来try...catch 来捕获错误。

最后会执行next(ret) 这里的ret 是把上一阶段处理完毕的异步结果传入next函数。

next函数先通过参数中的done 来判断是否是Generator 函数的最后一步,如果是就返回。
然后给了确保 参数是Promise对象 把参数转换为Promise对象
使用then 传入两个回调 如果成功 就调用onFulfilled (调用自身)
如果失败 抛出一个错误,并且终止执行。

你可能感兴趣的:(co是干啥用的)