JavaScript 是单线程的,事件循环(Event Loop)是它调度同步与异步任务的机制。执行顺序为:先执行调用栈中的同步代码;同步代码清空后,把微任务队列全部执行完(执行过程中新产生的微任务也会在本轮继续执行);然后取一个宏任务执行,之后再次清空微任务队列,如此循环。浏览器会在宏任务之间视情况插入渲染。
常见宏任务:setTimeout、setInterval、I/O、UI 事件、setImmediate(Node);常见微任务:Promise.then/catch/finally、queueMicrotask、MutationObserver,Node 中的 process.nextTick 优先级更高。
console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
console.log(4);
// 输出:1 4 3 2
易错点:微任务是「每轮清空整个队列」,宏任务是「每轮只取一个」;Node 与浏览器的事件循环阶段划分不同,回答时可说明以浏览器为主。追问:为什么 await 后面的代码等价于微任务。