把调用栈想成正在手里处理的咖啡杯:同一时刻只能端一杯。同步代码会先进调用栈,执行完就离开。
任务队列
setTimeout、用户点击、网络回调这类工作会被放入任务队列。调用栈清空后,事件循环才会取出下一件任务。
微任务
Promise.then、queueMicrotask 属于微任务。每个宏任务结束后,浏览器会先清空微任务队列,再进入下一轮任务。
所以常见顺序是:同步代码先执行,Promise 回调随后执行,最后才轮到 setTimeout(..., 0)。记住这个优先级,很多“为什么它先打印”的问题就会安静下来。