await后面的代码是同步执行吗?
async
和promise
并无本质区别,async
只是看起来更加同步,本质还是异步执行。来看一段代码。
1 | async function foo() { |
这段代码的输出结果是:1 3 2。而不是1 2 3。await
会等待右侧的Promise
执行完毕,并将后续代码 - console.log(2)
加入微任务队列。所以上述代码的执行过程是:
- 执行
console.log(1)
,输出1 - 执行
await Promise.resolve()
,将后续代码console.log(2)
加入微任务队列 - 执行
console.log(3)
,输出3 - 执行微任务队列中的代码,输出2
我们可以将foo
改写一下,它实际上等价于下面的代码。
1 | function foo() { |
由此,我们可以得出如下结论:
- await右侧的Promise同步执行。
- await后续的代码会在Promise resolve后背加入微任务队列等待后续执行。
再看一个例子:
1 | async function test() { |
这段代码的输出结果是:A B D C。执行过程如下:
- 首先执行test函数中的
console.log("A")
,输出A - 然后执行await右侧的Promise,由于
console.log("B")
是同步代码,所以输出B - 执行
setTimeout(resolve, 0)
,将resolve加入宏任务队列 - 执行
console.log("D")
,输出D - 注意此时微任务队列为空,所以执行宏任务队列中的resolve,此时await右侧的Promise执行完毕,将后续代码
console.log("C")
加入微任务队列 - 执行微任务队列中的代码,输出C
再看一个例子,你知道以下代码输出什么结果吗?
1 | async function async1() { |
答案是:1 7 4 6 2。来分析一下执行过程:
- 执行
async1()
,输出1 - 执行
await Promise.resolve().then(() => console.log(4))
,此时将console.log(4)
加入微任务队列。 - 执行
console.log(7)
,输出7 - 执行
async3()
,将console.log(6)
加入微任务队列 - 执行微任务队列中的代码console.log(4),输出4,此时
async1
中的await
右侧的Promise执行完毕,将后续代码console.log(2)
加入微任务队列 - 执行微任务队列中的代码
console.log(6)
,输出6 - 执行微任务队列中的代码
console.log(2)
,输出2
总结一下:
- 遇到
await
时,await
会暂停当前async
函数的执行,并等待右侧的Promise
执行完毕,然后async
函数后续代码加入微任务队列。 await
只是暂停当前async
函数的执行,并不会阻塞主线程的执行。当前async
函数外的代码会继续执行。- 从影响范围来说,
await
只影响当前async
函数,不影响其他函数。
await与Promise链
In JavaScript, await
can works with promise chain, it will get the resolved value of the last promise in the chain. For example:
1 | getData = () => |
In above code, getData()
returns a promise chain, the resolved value of the last promise in the chain is 3
, so the output of the code is 3
.
You can even append more promise chain when calling getData()
1 | async function test() { |