co的使用和实现原理

如下,node中读取文件fs.readFile,util.promisify将方法封装成promise返回。
有个想法:

  • 先读a.txt的内容,内容为b.txt;
  • 再去读b.txt的内容并返回
  • 用yield实现于是有了如下代码
const util = require('util');
const fs = require('fs')
let readFile = util.promisify(fs.readFile)
 function* read() {
     let data = yield readFile('./a.txt', 'utf8');
     data = yield readFile(data, 'utf8');
     return data;
}

接下来去调用这个read,写起来嵌套严重无法接受,于是产生了co

let it = read(); // it => next
let { value, done } = it.next();
value.then(data => {
    let { value, done } = it.next(data);
    value.then(data=>{
        let {value,done} =  it.next(data);
        console.log(value,done)
    })
})

TJ 写的 CO函数

  • 首先安装包 npm install co
  • 在js文件中引入CO,const co = require('co');
  • 使用CO
//co可以自动帮我们去执行next
co(read()).then(data=>{
     console.log(data)
 }).catch(err=>{
     console.log(err)
 })

可以CO返回的是一个Promise,我们实现一下CO
思路:

  • 将generator函数传入co方法,会自动调用next方法,直到next执行结果为true的时候,调用resolve返回结果,否则的话迭代执行next方法并把上次结果传递过去。。。
  • 因为next执行的结果可能是普通值或者promise 所以都统一封装一下Promise.resolve(value).then(next, reject)
//重要 请记下来
function co(it) {
    return new Promise((resolve, reject) => {
        // 异步的迭代  只能用递归的方法
        function next(data) {
            let { value, done } = it.next(data);
            if (done) { // 如果执行完毕则 完成
                resolve(value);
            } else {
                // 原生的promise 有优化 如果是promise 内部会直接把promise返回
                //不管是不是promise都封装一下
                Promise.resolve(value).then(next, reject)
            }
        }
       //第一次不用传值
        next();
    })
}

你可能感兴趣的:(co的使用和实现原理)