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函数的所有步骤

 

posted @ 2017-05-04 17:03  染简夕  阅读(3163)  评论(0编辑  收藏  举报