generator、async、await原理
generator原理
generator是一个带星号的函数,而且是可以暂停执行和恢复执行的。底层是通过协程实现的。
- 在generator函数内部执行一段代码,如果遇到yield关键字,则函数暂停执行,并将yield后面的内容返回给外部
- 外部通过next方法恢复函数的执行,gen.next(lastYieldResult)
- 如果遇到return关键字,则函数结束执行,并将结果返回给外部
function* genDemo() {
console.log('stage 1')
yield 'g1'
console.log('stage 2')
yield 'g2'
console.log('stage 3')
yield 'g3'
console.log('end')
return 'gend'
}
let gen = genDemo()
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())
console.log(gen.next())
输出
stage 1
{ value: 'g1', done: false }
stage 2
{ value: 'g2', done: false }
stage 3
{ value: 'g3', done: false }
end
{ value: 'gend', done: true }
generator+Promise实现async/await
async/await本质上是generator的语法糖,利用generator+promise可以实现在generator函数用同步方式写异步代码
// generator函数
function* foo() {
const res1 = yield Promise.resolve(1)
console.log(res1)
const res2 = yield Promise.resolve(2)
console.log(res2)
const res3 = yield Promise.resolve(3)
console.log(res3)
}
// generator执行器,实现在generator函数里用同步的方式写异步代码
function co(fn) {
const g = fn()
function doNext(result) {
if(!result.done) {
result.value.then(res => {
doNext(g.next(res))
})
}
}
const result = g.next() // 拿到第一个promise
doNext(result)
}
co(foo)