co.js是基于es6的generator实现的,至关于generator函数的一个自动执行器javascript
generator的简单介绍java
function* fn(){ before() yield firstYield() yield secYield() end() } let gen = fn()//生成构造器 gen.next()//执行到第一个yield的位置,即只执行before(),firstYield() gen.next()//执行到第二个yield的位置,只执行secYield() gen.next()//执行直到结束,执行end()
co.js的实现es6
将一个异步函数thunk化异步
原函数函数
fs.readFile(path,callback)
thunk化后函数spa
let readFile = (path) => (callback) => fs.readFile(path, callback)
将readFile的异步执行generator函数传入cocode
co(function* (){ let data1 = yield readFile('path1') console.log(data1)//显示path1的文件的内容 let data2 = yield readFile('path2') console.log(data2)//显示path2的文件内容 })
分析 co 函数blog
let co = (fn) => { let gen = fn()//将gen指向generator构造器 let next = (err, data) => { /**next函数,做用1.将上一步回调函数中data穿会给gen时期能为其余变量赋值,做用2:将gen向下一步运行,做用3.将next函数当成回调函数传给gen的某一步,使其将data传回next并执行下一步**/ let result = gen.next(data) if(! result.done){ result.value(next) } } next() }
分析执行过程ip
1.co(……)generator
执行let gen = fn (至关于gen =function* (){
let data1 = yield readFile('path1') console.log(data1)//显示path1的文件的内容 let data2 = yield readFile('path2') console.log(data2)//显示path2的文件内容 })
2.next()
执行let result = gen.next() (
至关于 let result = {done: false, value: readFile('path1')} (
至关于 let result = { done: false, value: (callback) => fs.readFile(‘path1’, callback)} ) ) 执行 if(! result.done ) //true||false 执行 result.value(next) ( 至关于 ((callback) => fs.readFile('path1',callback))(next) ( 至关于 fs.readFile('path1', next) ) )3. 当文件读取完毕以后,调用 fs.readFile()执行回调函数next(err,data)返回第二步4.执行完毕,执行完generator函数的全部步骤