co.js异步回调原理理解
co.js是基于es6的generator实现的,相当于generator函数的一个自动执行器
generator的简单介绍
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的实现
将一个异步函数thunk化
原函数
fs.readFile(path,callback)
thunk化后函数
let readFile = (path) => (callback) => fs.readFile(path, callback)
将readFile的异步执行generator函数传入co
co(function* (){ let data1 = yield readFile('path1') console.log(data1)//显示path1的文件的内容 let data2 = yield readFile('path2') console.log(data2)//显示path2的文件内容 })
分析 co 函数
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() }
分析执行过程
1.co(……)
执行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函数的所有步骤