koa之co源码解析

 es6的generator


let generator_func = function*() {};

let r = 3;

function* ap(a) {
  for (let i = 0; i < 3; i++) {
    a = a + r;
    // yield a a将会作为返回对象的value属性的值。
    yield a; // 碰到yield就暂停 保存当前堆栈,返回当前的a
  }
  // 函数没有return语句 最后一个value为undefined
}

let sum = ap(5);

// next方法:从函数体头部或者上一次停下的地方开始执行,直到遇到下一个yield语句为止。

sum.next(); // {value: 8, done: false}
sum.next(); // {value: 11,done: false}
sum.next(); // {value: 14,done : false}
sum.next(); // {value: undefined, done: true}

co的简单使用

let co = require("co");
let fs = require("fs");

// thunk 偏函数
function read(file) {
  return function(fn) {
    fs.readFile(file, "utf8", function(err, result) {
      if (err) return fn(err);
      fn(null, result);
    });
  };
}

// 使用thunkify写read函数
// let thunkify = require('thunkify');
// let read = thunkify(fs.readFile);

// generator function 只定义不执行
co(function*(next) {
  let c = 2;
  console.log(c);
  /**
   * 先执行yield read ,后执行赋值
   * 为什么a的值是read()异步返回的数据?
   * 因为a的值是gen.next()塞回去的
   */
  let a = yield read("demo.js");
  console.log(a.length);

  let b = yield read("package.json");
  console.log(b.length);
});

co的实现

核心思想是想办法递归的调用generator function的next(),直到执行完毕。_next()就是这样的递归方法

function co(fn) {
  return function(done) {
    let ctx = this;
    let gen = fn.call(ctx);
    function _next(err, res) {
      if (err) res = err;
      /**
       * it = { value: function(fn){
       *  fs.readFile(file,'utf8',fn)
       * },done: false}
       * read返回的函数中的fn 指的是 _next
       * .next是用来把结果返回出去并且继续往下执行代码,
       * 直到遇到下一个yield
       */
      let it = gen.next(res); 
      if (!it.done) {
        // _next用来循环调用.next的
        it.value(_next); 
      }
    }
    _next();
  };
}
为什么异步函数需要封装成thunk的偏函数的形式?
  因为我们需要再异步执行完成后,触发_next遍历方法
co接受的generator function 内部执行逻辑和co内部逻辑的执行顺序是什么样的?
  • 函数执行到 yield 关键字时,又中断了,执行 read 偏函数,
  • it.value(_next) 执行偏函数的返回函数,异步读取文件内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值