Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一道神奇的quiz #4

Open
AlvinYuXT opened this issue May 25, 2018 · 0 comments
Open

一道神奇的quiz #4

AlvinYuXT opened this issue May 25, 2018 · 0 comments
Labels
笔记 js笔记

Comments

@AlvinYuXT
Copy link
Owner

一道神奇的async quiz

Jake Archibald最近在twitter上出了一道简单的quiz题目,问大家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后面的表达式求值结果返回给左值。

@AlvinYuXT AlvinYuXT added the 笔记 js笔记 label May 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
笔记 js笔记
Projects
None yet
Development

No branches or pull requests

1 participant