阅读 1361

await会阻塞其所在表达式中后续表达式的执行

在进入正文之前,我们首先来看一段代码,这段代码会输出什么呢?

let x = 0;

async function test() {
    x += await 2;
    console.log(x);	// 输出什么?
}

test();
x = 1;
复制代码

输出3?还是2?正确答案是:2

如果你知道为什么会输出2,那就不用继续阅读本文了;但如果你清除这里面的原因,那么你可以跟随我一起分析一下:

  1. 首先我们先记住一句话,那就是异步函数(async方式声明的函数)不代表其函数内部的所有代码都是异步方式执行的,这句话什么意思呢?通俗讲就是:在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的,记住这句话以后我们再继续往下看

  2. 那么在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/

文章分类
前端
文章标签