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)