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函數的所有步驟

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM