实现async await功能

62 阅读1分钟

async函数

  • await只能在async函数中使用
  • async函数执行后返回一个promise对象
  • async函数执行时,遇到await会先返回一个promise对象,等到async函数中所有的逻辑执行完,这个promise对象状态才会发生变化
  • async函数是generator函数语法糖

async await的使用

function fn(nums) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(nums * 2)
        }, 1000)
    })
}
async function gen(value = 1) {
    const num1 = await fn(value)
    const num2 = await fn(num1)
    const num3 = await fn(num2)
    return num3
}
gen(2).then(res => {
    console.log(res)
})

通过generator函数结合promise实现async await功能

function fn(nums) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(nums * 2)
        }, 1000)
    })
}
function* gen(value = 1) {
    const num1 = yield fn(value)
    const num2 = yield fn(num1)
    const num3 = yield fn(num2)
    return num3
}
/**
实现async await功能
1.定义一个高阶函数:参数是一个函数,返回值也可能是一个函数,而且是一个具有async函数功能的函数A
2.async 执行后返回一个promise对象,那么A函数也应该是返回一个promise
3.A内部应该具有generator函数的自动执行器
4.async await是generator函数的语法糖,在执行async函数返回一个promise对象
5.当执行async函数时,遇到await,就直接将promise对象返回,然后等到函数执行完时,promise的状态才发生变化
6.await语句,往后的代码都在promise.then中执行
 */
function generatorToAsync(generator) {
    // 具有async函数功能的函数
    return function () {
        const gen = generator.apply(this, arguments)
        return new Promise((resolve, reject) => {
            function go(key, arg) {
                let next = null
                try {
                    next = gen[key](arg)
                } catch (error) {
                    return reject(error)
                }
                const { value, done } = next;
                if (done) {
                    return resolve(value)
                }
                // 当遇到一个await后,await后面的代码是在promise.then中执行
                // 也就是后面的代码是一个微任务
                Promise.resolve(next.value).then(val => go("next", val), err => go("throw", err))
            }
            go("next")
        })
    }
}
const myAsyncFn = generatorToAsync(gen)
myAsyncFn(2).then(res => {
    console.log(res)
})