在进入正文之前,我们首先来看一段代码,这段代码会输出什么呢?
let x = 0;
async function test() {
x += await 2;
console.log(x); // 输出什么?
}
test();
x = 1;
复制代码
输出3?还是2?正确答案是:2
如果你知道为什么会输出2,那就不用继续阅读本文了;但如果你清除这里面的原因,那么你可以跟随我一起分析一下:
-
首先我们先记住一句话,那就是异步函数(async方式声明的函数)不代表其函数内部的所有代码都是异步方式执行的,这句话什么意思呢?通俗讲就是:在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的,记住这句话以后我们再继续往下看
-
那么在test函数内部,哪些代码是按同步方式执行的呢?首先我们可以将
x += await 2
这行代码稍微变换一下形式,变换为:x = x + await 2
,表达式右边的x是取值操作,并且按同步方式执行的,所以在执行到await时,右边的x已经取值完成,并且被取到的值0
替换,然后才轮到test函数外的x = 1
这行代码执行,x += await 2
相当于x = 0 + await 2
,所以最终输出:2
现在,我们稍微对上面的代码做一下修改:
let x = 0;
async function test() {
x = (await 2) + x;// 把await放在x前面
console.log(x); // 这里又输出什么?
}
test();
x = 1;
复制代码
如果你已经明白了前面我所说的,那么我想你应该可以给出正确的答案,那就是输出:3。原因是:await 2
这次被放在了x
表达式的前面,所以x
的取值操作是异步执行的,也就是说x = 1
会先被执行,然后才是test函数中x
的取值操作,由于test函数中的x形成了闭包,所以x = (await 2) + x
相当于x = (await 2) + 1
,所以最终输出:3
结论
上面代码的关键是:test函数中x
的取值操作与x = 1
这行代码执行顺序先后的问题,所以我们可以得出一个结论:await会阻塞其所在表达式中后续表达式的执行
原文链接:https://www.guoyunfeng.com/2018/05/28/await/