爲了更加方便的處理異步操做問題,
如今最新的前端框架生態都開始用上了Generator和yield,
有的甚至已經開始使用最新的async、await語法了,
這兩樣都是基於Generator自動執行的原理。javascript
這裏就簡單理解下Generator自執行及async、await語法原理:前端
thunk函數指的是能將執行結果傳入回調函數,並將該回調函數返回的函數。
是否是有點抽象,舉個例子:java
var readFile = function (fileName) { return function (callback) { return fs.readFile(fileName, callback) } }
下面咱們來看下thunk函數怎樣執行es6
readFile('./package.json')((err, str) => { console.log(str.toString()) })
問: thunk的執行比普通函數要麻煩很多,那麼它有什麼優點呢?json
thunk函數的優點在於它能將異步操做返回結果的獲取權交給thunk函數的返回值,
而不是將異步操做結果傳入thunk函數自己的做用域內,這點很重要,
由於它能結合Generator語法讓Generator函數自動執行前端框架
es6的Generator函數,具體語法這裏就不介紹了,框架
咱們來編寫一個基於thunk函數的Generator:異步
let gen = function* () { let r1 = yield readFile('./package.json') console.log(r1.toString()) let r2 = yield readFile('./index.js') console.log(r2.toString()) }
咱們來手動執行一下這個Generator:async
let g = gen() let r1 = g.next() r1.value(function (err, data) { if (err) { throw err } let r2 = g.next(data) r2.value(function (err, data) { if (err) { throw err } g.next(data) }) })
能夠注意到,在咱們手動執行基於thunk函數的Generator時,
有不少代碼是能夠複用的,
沒錯,所謂的Generator自動執行就是把這些可複用的部分封裝成函數,
而後讓它們遞歸執行,直到執行完全部的yield。函數
下面就是Generator自動執行的核心代碼
function run(fn) { let gen = fn() function next(err, data) { let result = gen.next(data) if (result.done) { return } result.value(next) } next() }
能夠看到無非就是把可複用的部分封裝成next函數,而後讓其遞歸執行,
直到執行完全部的yield
其調用代碼爲:
run(gen)
這樣就將本來繁雜的異步操做封裝的十分簡單了
上面的例子是基於thunk函數的,而即將出現的es7的async、await語法是基於Promise的
這裏再上一個基於Promise的Generator的自動執行
//包裝返回Promise對象的函數 function readFile(fileName) { return new Promise((resolve, reject) => { fs.readFile(fileName, (error, data) => { if (error) { reject(error) } else { resolve(data) } }) }) } // 編寫Generator let gen = function* () { let r1 = yield readFile('./package.json') console.log(r1.toString()) let r2 = yield readFile('./index.js') console.log(r2.toString()) } // 編寫Generator執行器 function run(gen) { let g = gen() function next(data) { let result = g.next(data) if (result.done) { return result.value } result.value.then((data) => next(data)) } next() } //用Generator執行器自動執行 run(gen)
這個和基於thunk函數的大同小異,只是把函數返回值的獲取權以Promise的方式交出
但願這篇文章能幫助你簡單的理解Generator自執行及async、await語法原理 ^.^