目录

1. Async / Await是什么?

Async / Await是ES7提出的一种异步操作解决方案。从字面上很好理解, async是异步的意思,await是等待的意思,两者的用法也是根据他们的含义来的,async用于申明一个function是异步的,而await 用于等待一个异步方法执行完成。

Async / Await是基于Promise实现的,它能够使异步代码更像同步代码。await只能用在async函数中,不能用在普通函数中。

2. Async / Await的基本使用

2.1 async

async负责声明一个异步函数,它会返回一个Promise对象,可以使用 then 方法添加回调函数。只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

  • 如果async函数中return一个直接量,async会把这个直接量通过​​Promise.resolve()​​封装成Promise对象,
  • 如果async函数中没有返回值,就会返回​​Promise.resolve(undefined)​​。

通过​​then()​​可以取出Promise对象的值:

async function test() {
return 2020
}
const res = test()
console.log(res)

res.then(v => {
console.log(v)
})

输出口结果:

【JavaScript】浅谈Async / Await_js

2.2 await

await负责暂停服务异步的功能执行,进行等待。那它在等待什么呢?

它等待的是一个表达式,这个表达式的计算结果是Promise对象或者其他的值。如果是一个Promise对象,只要promise对象状态变为reject,await就会阻塞后面代码的执行,等待Promise对象状态变为resolve,得到的结果会作为then里面的参数。

这里的阻塞指的是async内部的阻塞,async函数的调用并不会阻塞。

async function testAsync() {
return await Promise.resolve("hello world");
}
console.log(testAsync())
testAsync().then(res => console.log(res))

输出结果:

【JavaScript】浅谈Async / Await_js_02

3. Async / Await与Promise的区别

Promise的出现解决了一直存在的地狱回调的问题,那为什么还要使用Async / Await呢?Promise的问题在于,一旦业务变得复杂,then内部的逻辑也就汇编的复杂,代码也就变的不好看。

下面来看一个例子:

function login () {
return new Promise(resolve => {
resolve('JavaScript')
})
}
function getUserInfo (token) {
return new Promise(resolve => {
if (token) {
resolve({
isVip: true
})
}
})
}
function getVipGoods (userInfo) {
return new Promise(resolve => {
if (userInfo.isVip) {
resolve({
id: 1,
price: 998
})
}
})
}
function showVipGoods (vipGoods) {
console.log("商品ID:"+ vipGoods.id)
console.log('价格:' + vipGoods.price)
}

上面的代码逻辑很简单,就是登录操作,后面的每一步都需要使用前看见的返回结果。我们来看看使用Promise怎么操作:

login().then(token => getUserInfo(token))
.then(userInfo => getVipGoods(userInfo))
.then(vipGoods => showVipGoods(vipGoods))

再来看看Async / Await如何操作:

async function call() {
const token = await login()
const userInfo = await getUserInfo(token)
const vipGoods = await getVipGoods(userInfo)
showVipGoods(vipGoods)
}
call()

这样写就比Promise更加简洁、清晰。

但是Async / Await的执行是同步的,这就会造成程序变慢,Promise是一种并发模式,Async / Await是一种继发模式。下面是两种方式的执行时间:

Async / Await:

【JavaScript】浅谈Async / Await_async_03


Peomise:

【JavaScript】浅谈Async / Await_await_04

我们可以看到,Async / Await的执行时间是Promise的近4倍,所以在使用的Async / Await的时候需要格外注意。

最后

我们可以将一些有依赖关系的回调函数的处理逻辑放在async里面,然后在非async的区域使用,这样可以减少then或者catch回调。