async-await的用法

681 阅读3分钟

async和await的基本用法

async函数

async函数在没有使用await时,和普通函数没有什么太大的区别,最主要的区别就是async函数始终返回一个Promise对象

async函数返回promise对象的状态

  • 不返回任何东西,相当于返回undefined
async funcion foo() {
    
}
console.log(foo())  // 打印的promise对象state是fulfilled,result为undefined。

image.png

  • 返回普通数据类似时
async function foo() {
    return 1 // foo函数返回值的promise对象state是fulfilled,result为1。
    return '1' // foo函数返回值的promise对象state是fulfilled,result为'1'。
    return []  // foo函数返回值的promise对象state是fulfilled,result为[]。
    return {}  // foo函数返回值的promise对象state是fulfilled,result为{}。
    return Symbol() // foo函数返回值的promise对象state是fulfilled,result为Symbol()。
}
  • 返回含有then方法的对象时, then方法会被调用,同时then方法会有两个参数resolve和reject调用了resolve,则返回的对象的状态为fulfilled调用了reject,则返回的对象的状态为rejected,如果在then方法里面没有调用resolve或者reject则返回的Promise对象的状态为pending
async function foo() {
    return {
        then(resolve, reject) {// then方法会被调用
            console.log(1) 
            resolve('then') // foo函数返回值的promise对象state是fulfilled,result为'then'。
        }
    }
}

  • 返回一个Promise对象,函数返回值的Promise的状态和return的Promise完全一致
async function foo() {
    return new Promise((resolve, reject) => {
        
    })
}
  • async函数中抛出错误
async function foo() {
    throw new Error('error')
    // foo函数返回值的promise对象state是reject,result为错误信息。
}
  • 总结一下,大多数情况下,async函数返回的Promise的状态为fulfilled,只有在返回值是一个Promise对象并且该对象的状态为rejected,或者是含有then方法的对象,并且在then方法中调用了reject函数,或者是函数执行过程中抛出错误,才会使得async函数返回的Promise的状态为rejected

await命令

正常情况下,await命令后面是一个Promise对象,如果不是,会被转成一个立即resolve的Promise对象await命令只能async函数内部使用,否则会报错。使用await时,必须保证上一层的函数时async函数,否则会报错

function foo() {
    await 1 // Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
}
async function foo() {
    await 1 // 这样不会报错
    function bar() {
        await 2 // 这样会报错
    }
}

在async函数中使用await

  • 在async函数中,如果使用了await命令,那么只要await命令跟着的promise对象状态没有变成fulfilled,那么await后面的代码都不会执行。
async function foo() {
    await new Promise((resolve, reject) => {
        
    })
    // 只要上面没有调用resolve将promise状态变成fulfilled,那么这里的代码会被一直阻塞,不会被执行。
    // 这里的代码相当于上一个Promise的then方法,是一个微任务。
    console.log('后面的代码')
}
  • 当await函数跟着的promise对象为rejected时,会抛出一个错误,并且终止程序。
async function foo() {
    await new Promise((resolve, reject) => {
        reject('reject')
    })
    // 这里的代码不会被执行
    console.log(1)
}
foo()
  • 为了防止上面的情况发生,可以将await放在try...catch语句中
async function foo() {
    try {
        await new Promise((resolve, reject) => {
            reject('reject')
        })
    } catch(err) {
        console.log(err)
    }
    // 这里的代码会被执行。
    console.log(111)
}