async&await

141 阅读3分钟

async&await

什么是async和await?

  • async

    MDN:

    async function 用来定义一个返回 AsyncFunction 对象的异步函数。异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的 Promise 返回其结果。如果你在代码中使用了异步函数,就会发现它的语法和结构会更像是标准的同步函数。

    简单来说,async函数就是用于将异步的Promise转换成类似同步函数的形式。

  • await

    async函数中的关键字。await值能在async函数中使用。

    await后面必须接一个接一个返回了 Promise的函数的调用形式(实际上是await + Promise) 。

使用async和await

示例代码:

function random(){
    return new Promise((resolve)=>{
        setTimeout(()=>{
            let n = parseInt(Math.random() * 6 + 1 , 10 )
            let b = 0
            resolve({n,b})
        },3000)
    })
}

async function specialFn(){
    let result  = await random()
    console.log(result)
}

specialFn() // {a:[1~6],b:0}
console.log(specialFn()) // Promise

上面 specialFn 的内部,执行顺序实际上是 先执行 await random(),等待random()返回结果后,赋值给 n ;接着才继续往下执行。

如果没有 await, 它并不会等待 random() 结束后才会继续执行,而是直接往下执行。 在上面的例子中,如果我们删去await,specialFn()console.log(result)结果就是 Promise对象,而不是resolve传递过来的结果。

async 函数返回的是一个 Promise,所以async await实际上就是Promise的语法糖,让Promise变得更“同步”更好理解。

由于 async function 是异步的,所以上面的代码中,我们会先执行console.log(specialFn()),然后才执行2个specialFn()

async中获取结果与错误信息

function guessNum(largeORsmall){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            let n = parseInt(Math.random() * 6 + 1 , 10 )
            if(n>3){
                if(largeORsmall==='large'){
                    resolve(n)
                }else{
                    reject(n)
                }
            }else{
                if(largeORsmall==='small'){
                    resolve(n)
                }else{
                    reject(n)
                }
            }
        },3000)
    })
}

async function specialFn(){
    try{
       let result  = await guessNum('large') 
       console.log(`'bingo the number is' ${result}`)
    }catch(error){
       console.log(`'sorry the number is' ${error}`)
    }
}

specialFn() 
console.log(specialFn())

在Promise中,我们可以通过,resolve和reject的第一个参数来传递需要的内容。比如,例子中我们传递的就是随机数n。如果需要传递多个变量,可以通过对象的形式。

在async函数中,获取resolve传递的内容很简单,let result = await guessNum('large') result获取的就是resolve传递的内容。

而获取reject传递过来的‘错误信息’则需要通过catch

多个Promise怎么解决?

如果直接使用Promise 我们可以通过 all race 的API来解决那么await呢?

首先明确的是,await后面只能接一个Promise

如果 await后面要接多个Promise也需要借助 all race的帮助

async和await的意义

这种方式比起Promise的then更加复杂,为什么要是使用async await 呢?因为对同步的追求。

Promise.then(f1,f2)的形式,对逻辑不太友好,我们并不清楚f1 f2 何时执行。但是async await的形式就非常清晰,我们通过这种方式,把异步函数,转换成可以用类似于同步函数的形式,使得代码阅读起来更加顺畅。