文章目录

  • 什么是async函数
  • 基本用法
  • 传统promise和async的区别
  • async内部异常处理


什么是async函数

async 和 await 是用来处理异步的。即你需要异步像同步一样执行,需要异步返回结果之后,再往下依据结果继续执行。

async 是“异步”的简写,而 await 可以认为是 async wait 的简写。async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。

一句话,它就是 Generator 函数的语法糖。

基本用法

当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

async function fiveInAsync() {
  for(let i = 1; i <= 5; i++) {
    console.log(i);
    await sleep(1000);
  }
}

传统promise和async的区别

相比传统的 Promise 写法,async-await 让我们书写代码时更加流畅,也增强了代码的可读性。

Promise 处理多异步流程

const getUp = function () {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log('get up at 7:00.')
            resolve();
        }, 100);
    });
}
const washFace = function () {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log('wash face at 7:10.')
            resolve();
        }, 100);
    });
}
const brushTeeth = function () {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log('brush teeth at 7:20.')
            resolve();
        }, 100);
    });
}
const happyDay = function () {
    getUp().then(washFace()).then(brushTeeth());
}
happyDay();

async, await处理多异步流程

const getUp = function () {
     return new Promise((resolve) => {
         setTimeout(() => {
             console.log('get up at 7:00.')
             resolve();
         }, 100);
     });
 }
 const washFace = function () {
     return new Promise((resolve) => {
         setTimeout(() => {
             console.log('wash face at 7:10.')
             resolve();
         }, 100);
     });
 }
 const brushTeeth = function () {
     return new Promise((resolve) => {
         setTimeout(() => {
             console.log('brush teeth at 7:20.')
             resolve();
         }, 100);
     });
 }
 const happyDay = async function () {
     await getUp();
     await washFace();
     await brushTeeth();
 }
 happyDay();

对比可以看出采用async, await方式代码书写明显更简洁,而且可阅读性更好。

async 函数内部抛出错误或者 await 关键字后面的表达式抛出错误,会使 async 函数返回的 Promise 对象从 pending 状态变为 reject 状态,从而可以被 catch 方法捕获错误。而且,Promise 对象的状态一旦改变就不会再变,之后的异步任务就不会执行了。

await关键字后面的表达式可以是 Promise 对象,也可以是其他数据类型。如果是其他数据类型,则会通过 Promise.resolve 将其转换为 Promise 对象
async函数内部如果有多个 await 关键字,其后的异步任务会继发执行。如果每一个异步任务不相互依赖,则可以使用 Promise.all 让其并发执行,这样可以在同样的时间里完成多个异步任务,提高函数执行效率。

async内部异常处理

如果在 async 内部如果抛出错误或者出现异常,会被 then 方法的错误处理函数捕获或者 catch 方法捕获。

async function as () {
  throw new Error('出错拉!')
}
as().then(data => {
  console.log(data)
}).catch(err => {
  console.log(err)
})

对于async内部抛出的错误,可以使用 try…catch 来捕获异常。虽然 try…catch 只能用于捕获同步任务,但是 await 关键字可以使得异步任务同步化,因此可以结合 try…catch 和 await 关键字捕获异步任务。