为何这段JS代码执行时1先于4打印?请基于事件循环与微任务队列解析
事件循环与微任务队列视角下的代码执行顺序解析
先看你给出的代码:
async function check() { await Promise.resolve(console.log(1)); console.log(2); } console.log(3); check(); console.log(4);
实际输出是3,1,4,2,咱们一步步拆解执行逻辑:
第一步:执行同步代码输出3
主线程启动后,首先执行最外层的console.log(3),直接输出3。第二步:调用异步函数
check(),同步输出1并挂起后续代码
调用check()进入函数体后,先处理await Promise.resolve(console.log(1)):- 先执行
Promise.resolve()的参数console.log(1)——这是同步代码,直接输出1; Promise.resolve()会立刻返回一个已决议(fulfilled)的Promise;- 遇到
await,会暂停当前异步函数的执行,把函数里await之后的代码(也就是console.log(2))加入微任务队列,然后退出check()函数,回到主线程。
- 先执行
第三步:主线程继续执行同步代码输出4
主线程不会等待异步函数完成,继续执行剩余的同步代码console.log(4),输出4。第四步:主线程同步任务清空,处理微任务队列输出2
当主线程的所有同步任务执行完毕后,事件循环会优先处理微任务队列里的任务,取出之前放入的console.log(2)执行,输出2。
纠正你的误解
你以为异步函数会进入Web API处理,但这里的Promise.resolve()是同步创建的已决议Promise,不会进入Web API(Web API负责处理定时器、AJAX这类真正的异步IO操作)。await针对已决议的Promise时,只会把后续代码放入微任务队列,而微任务的执行优先级高于所有宏任务,必须等主线程同步任务全部完成后才会被处理。
内容的提问来源于stack exchange,提问作者Rehmat Sayany
相关产品推荐
相关产品推荐

