1、前言
async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise。
2、详解
async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。需要注意的是await关键字只在async函数内有效,如果在async函数体之外使用它,会抛出语法错误。
2.1、async
async函数返回一个 Promise对象,可以使用then方法添加回调函数。只要使用async,不管函数内部返回的是不是Promise对象,都会被包装成Promise对象。
- 函数返回非Promise对象

可以看出函数直接返回字符串时,返回的是Promise对象,相当于直接通过Promise.resolve()将字符串封装为Promise对象。如果函数没有返回值时,PromiseResult结果为undefined。

可以看出返回的也是Promise对象。
2.2、await
await关键字可以跟在任意变量或者表达式之前,但通常await后面会跟一个异步过程。await使用时,会阻塞后续代码执行。我们先抛开async,单独谈await。

可以看出,使用了await后,必须得等testAsync方法执行完后,才会执行后续代码。也可以尝试一下把testAsync前的async去掉,看看跟加上await时有啥区别。
2.3、async、await结合使用
语法:
1 | async function 函数名() { |
示例代码:
1 | function testAsync() { |
上图可以看出遇到第一个await后,立即返回了Promise对象,然后再按顺序去执行testAsync函数,等待testAsync函数执行后再去执行testAsync2函数。还可以看出async函数可以简化Promise的语法,以往我们需要使用.then去处理回调,现在我们可以使用await像写同步代码一样去写异步代码。
再升级一下,在上面的基础上再加入两个普通函数:
1 | function fun1() { |
梳理一下函数的执行过程:
- 先执行函数1
- 进入test函数并输出开始
- 在test函数中遇到await,立即返回Promise对象
- 执行函数2
- 执行test函数中的testAsync方法
- 等到test函数中的testAsync方法执行完后,继续执行testAsync2方法
- test函数结束
可以看出,async函数在遇到await后会立即返回Promise对象,继续执行async函数外部后续逻辑,async函数内部会被await阻塞并按顺序执行代码逻辑。
2.4、async、await异常处理
await后面的函数是有可能出现异常的,所以最好把await命令放在try…catch代码块中。如果await后是Promise对象,也可以使用.catch进行捕获。
1 | // 第一种写法 |
3、总结
async函数在遇到await后会立即返回Promise对象,继续执行async函数外部逻辑,async函数内部会被await阻塞并按顺序执行代码逻辑。
可以使用try…catch或.catch对async函数进行异常处理。