async await 和 Promise的关系

123 阅读2分钟

async await

async await 是 Promise和生成器的语法糖

将function 的* 换成了async,将 yield 换成了await

function PromiseData(value){
    return new Promise((resolve,reject){
        setTimeOut(()=>{
            //console.log('aaa')
            resolve(value)
        },1000)  
    })
}
​
function* foo(){
   const res1 = yield PromiseData('aaa')
   const res2 = yield PromiseData(res1+'bbb')
   const res3 = yield PromiseData(res2+'ccc')
   console.log("res3:",res3)
}
​
const Gen = foo()
1.Gen.next() // 拿到的是 { done:false,value:Promise对象 }
2.Gen.next().value.then(res =>{
}) //调用Promise对象里面的 then 方法
3.Gen.next().value.then(res =>{
    Gen.next(res)
}) //将Promise里面返回的res作为参数 传递到 yield 的返回值里面(res1 接收)
4.然后在取到里面的value调用里面的 then 方法
​
Gen.next().value.then(res =>{
    Gen.next(res).value.then(res =>{
       Gen.next(res).value.then(res =>{
            Gen.next(res)
        })
    })
}) 
​
//将上面的函数进行一个封装
​
function execGen(GenFn){ //传递一个生成器函数进来
    const Gen = Genfn() 
    function exec(res){
        const result = Gen.next(res) //先调用一次next函数,获取里面的done进行判断
        if( result.done ) { //如果done为 ture ,说明后续没有了,返回 value
            return result.value
        }
        result.value.then(res=>{  // done为false的话,则调用 Value里面的Promise里面的then方法,然后将 得到的数据作为参数进行传递 
            exec(res)
        })
    }
    
    exec() //调用函数
}
​
execGen(foo)  //调用函数
​
***这样就能拿到不断回调函数的结果,也不会产生回调地狱,代码结构清晰***

通过上面的运算就能实现 不断的then调用,

最后将 function*换成 async function yield换成 await

async

async函数内部没有特殊处理的话,和普通函数在执行流程上没有区别

异步函数的返回值是一个 Promise 对象,直接返回一个数据的话,相当于调用了resolve(data),同理可以返回一个新的Promise对象或者 thenable 对象

可以在后续函数中使用 .then 接收使用数据,而普通函数默认返回undefined

async function foo(){
    return 666
}
​
const bar = foo()
console.log(bar); /// Promise {666}
​
​
//普通函数
function foo1(){
    return 555
}
​
const bar1 = foo1()
console.log(bar1); /// 555

await

await可以看成是Promise进入 fulFilled 状态之后的一个回调

await后面通常跟着一个表达式,表达式会返回一个Promise对象,

await后面的函数相当于等到这个回调结束之后调用then方法