实现async await

280 阅读1分钟

async await和 generate

generate是协程的实现,可以与父协程交换控制权,并且能保存当前的调用栈
async就相当于*
await就相当于yield
通过自动执行生成器函数,就模拟了async await

这里没有处理异常的情况

模拟实现

// 异步任务
function asyncTask(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
           resolve(num + 1)
        }, 2000)
    })
}

// 生成器函数
// 要执行的任务
function* tasks() {
    console.log(1)
    let num1 = yield asyncTask(1)
    console.log(2)
    let num2 = yield asyncTask(2)
    console.log(3)
    return num1 + num2
}

// 自动执行,接收一个生成器函数
function co(generate) {
    let g = generate() // 获得一个生成器
    return new Promise((resolve, reject) => {
        auto(g, resolve, reject)
    })
}

// g 生成器
// resolve co函数的resolve
// reject co函数的reject
// res 获取asyncTask的结果,传给下一个next函数
function auto(g, resolve, reject, res) {
    let result = g.next(res)
    if(!result.done) {  // 生成器是否结束了
        result.value.then(res => {
            auto(g, resolve, reject, res)
        })
    } else {
        resolve(result.value)
    }
}

co(tasks).then(res => {
    console.log(res)
})

// 1
2秒后
// 2
2秒后
// 3
// 5