一道关于async神奇的测试题

问大家x的输出是什么。代码如下:

let x = 0;

async function test() {
    x+= await 2;
    console.log(x);
}

test();
x += 1;
console.log(x)

看到这里我想,这不就是在考microTask和marcoTask吗?那么答案应该不难,执行顺序是这样的:

  1. 先执行test函数,test函数中直接就进入到x+=await 2了,那么放到microTask中
  2. 执行x+=1
  3. 执行console.log(x),输出结果是1
  4. 当前作用域没有macro要执行了,所以执行microTask,执行x+=await 2;console.log(x)输出结果应该是3

错!!!

实际上不是这样的,而这里我对async/await中什么内容放到microtask也存在错误的理解。正确的执行顺序是这样的

  1. 执行test函数此时x+=await 2等价于x = x + await Promise.resolve(2),表达式右边在求值的时候遇到了await,所以这个时候x已经求值了,也就是说上面的函数等价于x = 0 + await Promise.resolve(2)。这里还有一点需要注意的是Promise只有then和catch里面的是真正异步执行的,想new Promise(resolve=>{console.log(123)})这种事直接同步执行的,而这里的Promise.resolve(2)也是同步执行的。
  2. 这个时候继续执行x+=1;console.log(x)输出的结果是1
  3. macroTask执行结束之后去执行microTask,这个时候就会回来执行x = 0 + 2; console.log(x),所以这个时候输出的是2

注意:await后面的语句并不是放到micro去执行的,而是直接同步执行的。也就是说await并不直接将后面要执行的代码放到microTask中,await只是等待microTask执行完才把await后面的表达式求值结果返回给左值。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值