async和await

  1. await后面接一个会return new promise的函数并执行它
  2. await只能放在async函数里
  • 使用async和await获取成功的结果
function 摇色子(){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        setTimeout(()=>{
            resolve(sino)
        },3000)
    })
}
async function test(){
    let n =await 摇色子()
    console.log(n)
}
test()

上面这段代码async中使await 摇色子()先执行,等到三秒后执行完再把得到的结果赋值给左边的n,也就是说test函数需要三秒钟才执行完成,所以test函数是异步的,因此前面必须写async

  • 获取失败的结果
function 摇色子(猜测){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        if(sino > 3){
            if(猜测 === '大'){
                resolve(sino)
            }else{
                reject(sino)
            }
        }else{
            if(猜测 === '大'){
                reject(sino)
            }else{
                resolve(sino)
            }
        }
        setTimeout(()=>{
            resolve(sino)
        },300)
    })
}
async function test(){
    try{
        //把await及获取它的值的操作放在try里
        let n =await 摇色子('大')
        console.log('赢了' + n)
    }catch(error){
      //失败的操作放在catch里
        console.log('输了' + error)
    }
}
test()

把await和成功后的操作放到try里,失败的放在catch

  • 为什么要用await
    为了使我们的异步代码,更像同步的代码

  • 有多个promise,怎么拿到所有的promise都结束后的结果
    比如有两个色子,我想得到这两个色子的点数

  1. 使用promise
function 摇色子(猜测){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        if(sino > 3){
            if(猜测 === '大'){
                resolve(sino)
            }else{
                console.log('error')
                reject(sino)
            }
        }else{
            if(猜测 === '大'){
                console.log('error')
                reject(sino)
            }else{
                resolve(sino)
            }
        }
        setTimeout(()=>{
            resolve(sino)
        },300)
    })
}
Promise.all([摇色子('大'),摇色子('大')]).then((x)=>{console.log(x)},(y)=>{console.log(y)})

promise.all里面跟一个数组,数组的每一项是一个返回promise的函数调用,then的第一个参数是所有的promise都成功后调用,拿到所有promise的结果是一个数组;第二个参数拿到的是第一个失败的值

  1. 使用await
    await是直接获取多个promise的结果的,因为Promise.all()返回的也是一个promise所以如果要使用await拿到多个promise的值,可以直接await Promise.all()
async function test(){
    try{
        let n = await Promise.all([摇色子('大'),摇色子('大')])
        console.log(n)
    }catch(error){
        console.log(error)
    }
}
test()
  • async函数会返回一个promise,并且Promise对象的状态值是fullfiled(成功的)
  1. 如果你没有在async函数中写return,那么这个 async 函数返回的就是一个值为 undefined 的 fulfiled 状态的 Promise
  1. 如果你写了return,那么return的值就会作为你 fulfiled 状态的 Promise 的值
  1. 如果 async 函数里 return 的是一个 Promise 那么返回的就是这个 Promise 执行成功后的结果



    如果上面使用 await 获取结果那么会等到Promise 整个链路都执行完再获取结果也就是你不管.then 多少层级都会等他全执行完

拿到的结果肯定是最后一层的

await 等的是一个 fulfiled 状态的 Promise

await 等到之后,做了一件什么事情?
那么右侧表达式的结果,就是await要等的东西。
等到之后,对于await来说,分2个情况

  • 不是promise对象
  • 是promise对象

如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。

  • 如果asycn里的代码都是同步的,那么这个函数被调用就会同步执行
async function fn(){
  console.log('a')
}
fn()
console.log('b')
//a
//b
  • 如果在await后面接的这个promsie都是同步的,后面的promise会同步执行,但是拿到这个值还是得等待(特别注意:如果promise没有一个成功的值传入,对await来说就算是失败了,下面的代码就不会执行),所以不管await后面的代码是同步还是异步,await总是需要时间,从右向左执行,先执行右侧的代码,执行完后,发现有await关键字,于是让出线程,阻塞代码
function fn(){
    return new Promise(resolve=>{
        console.log(1)
    })
}
async function f1(){
    await fn()
    console.log(2)
}
f1()
console.log(3)
//1
//3

这个代码因为fn是属于同步的,所以先打印出1,然后是3,但是因为没有resolve结果,所以await拿不到值,因此不会打印2

function fn(){
    return new Promise(resolve=>{
        console.log(1)
        resolve()
    })
}
async function f1(){
    await fn()
    console.log(2)
}
f1()
console.log(3)
//1
//3
//2

这个代码与前面相比多了个resolve说明promise成功了,所以await能拿到结果,因此就是1 3 2

你可能感兴趣的:(async和await)