async与await

async 是异步的意思, await 则可以理解为 async wait 。所以可以理解 async 就是⽤来声

明⼀个异步⽅法,⽽ await 是⽤来等待异步⽅法执⾏

21.3.1. async

async 函数返回⼀个 promise 对象,下⾯两种⽅法是等效的

1
2
3
4
5
6
7
8
9
10
11
12
13
1 function f() {

2 return Promise.resolve('TEST');

3 }

4 *// asyncF is equivalent to f!*

5 async function asyncF() {

6 return 'TEST';

7 }

21.3.2. await正常情况下, await 命令后⾯是⼀个 Promise 对象,返回该对象的结果。如果不是 Promise 对

象,就直接返回对应的值

1
2
3
4
5
6
7
8
9
10
11
1 async function f(){

2 *//* *等同于*

3 *// return 123*

4 return await 123

5 }

6 f().then(v => console.log(v)) *// 123*

不管 await 后⾯跟着的是什么, await 都会阻塞后⾯的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1 async function fn1 (){

2 console.log(1)

3 await fn2()

4 console.log(2) *//* *阻塞*

5 }

6 async function fn2 (){

7 console.log('fn2')

8 }

9 fn1()

10 console.log(3)

上⾯的例⼦中, await 会阻塞下⾯的代码(即加⼊微任务队列),先执⾏ async 外⾯的同步代

码,同步代码执⾏完,再回到 async 函数中,再执⾏之前阻塞的代码

所以上述输出结果为:

1
1 , fn2 , 3 , 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1 async function async1() {
2 console.log('async1 start')
3 await async2()
4 console.log('async1 end')
5 }
6 async function async2() {
7 console.log('async2')
8 }
9 console.log('script start')
setTimeout(function () {
console.log('settimeout')
})
async1()
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('promise2')
})
console.log('script end')

分析过程:

  1. 执⾏整段代码,遇到 console.log(‘script start’) 直接打印结果,输出 script
  2. s遇 t到 ar定 t时器了,它是宏任务,先放着不执⾏
  3. 遇到 async1() ,执⾏ async1 函数,先打印 async1 start ,下⾯遇到 await 怎么办?

先执⾏ async2 ,打印 async2 ,然后阻塞下⾯代码(即加⼊微任务列表),跳出去执⾏同步

代码

4.

跳到 new Promise 这⾥,直接执⾏,打印 promise1 ,下⾯遇到 .then() ,它是微任

务,放到微任务列表等待执⾏

  1. 最后⼀⾏直接打印 script end ,现在同步代码执⾏完了,开始执⾏微任务,即 await 下⾯的

代码,打印 async1 end

  1. 继续执⾏下⼀个微任务,即执⾏ then 的回调,打印 promise2
  2. 上⼀个宏任务所有事都做完了,开始下⼀个宏任务,就是定时器,打印 settimeout

所以最后的结果是: script start 、 async1 start 、 async2 、 promise1 、 script

end 、 async1 end 、 promise2 、 settimeout