问大家x的输出是什么。代码如下:
let x = 0;
async function test() {
x+= await 2;
console.log(x);
}
test();
x += 1;
console.log(x)
看到这里我想,这不就是在考microTask和marcoTask吗?那么答案应该不难,执行顺序是这样的:
- 先执行test函数,test函数中直接就进入到x+=await 2了,那么放到microTask中
- 执行x+=1
- 执行console.log(x),输出结果是1
- 当前作用域没有macro要执行了,所以执行microTask,执行x+=await 2;console.log(x)输出结果应该是3
错!!!
实际上不是这样的,而这里我对async/await中什么内容放到microtask也存在错误的理解。正确的执行顺序是这样的
- 执行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)也是同步执行的。
- 这个时候继续执行x+=1;console.log(x)输出的结果是1
- macroTask执行结束之后去执行microTask,这个时候就会回来执行x = 0 + 2; console.log(x),所以这个时候输出的是2
注意:await后面的语句并不是放到micro去执行的,而是直接同步执行的。也就是说await并不直接将后面要执行的代码放到microTask中,await只是等待microTask执行完才把await后面的表达式求值结果返回给左值。