一,前言
上篇,主要介绍了 generator 生成器函数的使用和实现原理,主要涉及以下几个点:
generator 简介:特性、用法、功能分析;
generator 实现原理分析;
前面的 Promise 仅仅是对异步回到进行了优化,在 Promise 的内部依然还是存在回调的,所以实际上并没有解决“回调地狱”的问题;
最终解决方案还要使用 async/await,async/await 是基于 generator 的语法糖,而为了搞清楚 async/await 的原理,需要先对 generator、co 进行了解;
本篇,继续介绍 co 库:自动执行 Generator 生成器函数;
二,co 库的简介
1,co 库的作用
2,co 库的使用
const util = require('util');const fs = require('fs');let readFile = util.promisify(fs.readFile)
// generator 生成器函数function * read() { let data = yield readFile('./a.txt','utf8'); data = yield readFile(data,'utf8'); return data;}
// 方法一:Generatorlet it = read(); // 生成器函数返回一个 Iterator 迭代器对象let {value:v1, done:d1} = it.next(); // 注意:第一个next传参是无效的v1.then(data=>{ console.log(data) // b.txt let {value:v2, done:d2} = it.next(data); // 将第一次的结果作为第二次的入参 return v2}).then(data=>{ console.log(data) // 执行结果:c})
// 方法二:使用 co 库const co = require('co')// co 方法:包装 generator 生成器函数,内部自动执行完成,返回一个 promiseco(read()).then(data=>{ console.log(data); // 执行结果:c})
复制代码
对比 Generator 和 co 两种方案:
三,co 库的实现
手写一个 co 方法:主要使用了”异步迭代“的思想;
/** * 自动执行迭代器 * @param {*} it generator执行返回的迭代器函数 * @returns */function co(it) { return new Promise((resolve, reject) => { function next(data) { // 将上一次的结果作为下一次的入参 let { value, done } = it.next(data); if (done) { // 迭代器执行完成,返回最终结果 resolve(value); } else { // 备注:使用 Promise.resolve 将 value 包装成Promise // 成功:说明迭代器还没有执行完,继续递归调用 next,直至迭代器完成 Promise.resolve(value).then(next, reject);// 注意此处的 next 传入的是当前 function } }
next();// 第一次调用 next 时,传参是无效的 })}
复制代码
四,结尾
本篇,主要介绍了 co 库的使用和实现原理,主要涉及以下几个点:
co 库的简介:特性、用法、功能分析;
co 库的实现和原理分析;
下一篇,继续介绍 async/await:generator 语法糖,嵌套回调问题的最终解决方案;
评论