bug收集:专门解决与收集bug的网站
最近,在写在项目中很多的地方,用到了async和await。
发现了和理解的有些不一样,
下面有几道网上看到的题,大家可以做做,看看和你想的是否一样
async function test() {
console.log(0)
await console.log(111);//在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的
console.log(555) //倒数第二个输出
console.log(556665)//最后一个输出
}
function test1(){
console.log(22)
}
test1();
test();
console.log(10);
输出结果:
总结:异步方法里面await会阻塞该方法内部后续的进程(等待时间比同步方法久,先执行同步方法)
再看以下示例帮助理解:
let x = 0;
async function test() {
x += await 2;
console.log(x); // 输出什么?
}
test();
x = 1;
输出3?还是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会阻塞其所在表达式中后续表达式的执行。
苟有恒 , 何必三更眠五更起