CO原理读后感

623 阅读2分钟

什么是CO?

co 模块是著名程序员 TJ Holowaychuk 于 2013 年 6 月发布的一个小工具,用于 Generator 函数的自动执行。

复习Generator

generator是ES6提供的一种解决异步编程方案;形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
generator总是返回一个指向内部状态的指针对象,然后必须调用该指针对象的next方法是的指针移向下一个状态。
关键字 _yield 是暂停执行标志,_而_next_方法是可以恢复执行

开始学习CO

co接受Generator函数作为参数,通过return一个Promise方式来交回执行权。

function co(gen) {
  var ctx = this;

  return new Promise(function(resolve, reject) {
  });
}

然后在Promise对象里面判断参数gen是否为Generator函数,如果是则执行否则直接resove出该参数

function co(gen) {
  var ctx = this
  var args = slice.call(arguments, 1)
  return new Promise(function (resolve, reject) {
    	if(typeof gen === 'function') gen = gen.apply(ctx)
			if(!gen || typeof gen.next !== 'function') resolve(gen)
  })
}

封装onFulfilled函数能够捕捉抛出错误


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

最后就是next函数,递归调用自身来达到自动执行next方法目的

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函数当做形参,然后执行next方法,根据done判断何时执行resove方法,通过每次Promise执行完then函数后回调onFulfilled递归执行next方法,通过next方法传递上一个状态值。

公共函数

toPromise、thunkToPromise、arrayToPromise、objectToPromise、defer、 isPromise、isGenerator、isGeneratorFunction、isObject