JavaScript 运行在单线程上,因此一次只能执行一个操作。事件循环让它能够处理异步工作而不阻塞:它运行调用栈,当栈为空时,从队列中拉取回调。
有两个队列具有不同的优先级:
- 微任务:Promise 回调(
.then)、queueMicrotask。在每个任务后,在渲染前。
setTimeout、I/O、UI 事件。每个循环迭代处理一个。console.log("1"); // sync
setTimeout(() => console.log("2"), 0); // macrotask
Promise.resolve().then(() => console.log("3")); // microtask
console.log("4"); // sync
// Output: 1, 4, 3, 2
1、4。3。2。这就是为什么 Promise.then 总是在 setTimeout(…, 0) 之前运行,即使两者都是「异步」——微任务有优先级。
// ❌ blocks the single thread — UI freezes for 5 seconds
while (Date.now() - start < 5000) {}
长同步工作会阻塞所有内容(渲染、点击)。将重型 CPU 工作卸载到 Web Worker(一个真正的独立线程)。
理解事件循环解释了异步顺序、为什么 Promise 在定时器之前解决,以及为什么永远不要阻塞主线程——这是所有异步 JavaScript 的核心心智模型。