什么是javascript事件循环_它如何管理任务队列【教程】

10次阅读

javaScript事件循环是宏任务与微任务交替执行的协作机制,微任务总在每次宏任务结束后立即连续执行;setTimeout等为宏任务,promise.then等为微任务;await后代码是否异步取决于等待值类型

什么是javascript事件循环_它如何管理任务队列【教程】

javascript 事件循环不是“轮询检查”,也不是“定时扫描”,它是一套严格按规范执行的协作机制——宏任务与微任务交替清空,且微任务总在每次宏任务结束后立即、连续执行完毕。

宏任务和微任务怎么区分?哪些常见操作属于哪一类?

区分关键看规范定义和宿主环境实现,不是看“耗时长短”或“是否异步”。比如 setTimeoutsetIntervalI/O 回调ui 渲染 是宏任务;而 Promise.then/catch/finallyMutationObserverqueueMicrotask 是微任务。

  • Promise.resolve().then() 会进微任务队列,哪怕里面是空函数或同步 throw
  • setTimeout(() => {}, 0) 一定进宏任务队列,即使延迟为 0,也要等当前任务+所有微任务跑完才执行
  • async function 内部的 await 表达式后代码,本质被编译成 Promise.then,所以也进微任务
  • requestIdleCallback 是宏任务,不是微任务(常被误认)

为什么 await 后面的代码不总在下一个 tick 执行?

因为 await 的行为取决于它等待的值:如果等待的是已决议的 Promise(如 await Promise.resolve(42)),后续代码会作为微任务入队;但如果等待的是一个普通值(如 await 42),V8 会直接同步执行,不产生微任务。

  • Promise → 微任务调度 → 下一轮微任务阶段执行
  • 等非 Promise 值(StringnumberNULL)→ 无异步开销 → 同步继续
  • 这个差异会导致调试时“有时快有时慢”,容易误判执行时机

node.js浏览器的事件循环有啥实际差别?

Node.js 的事件循环有 6 个明确阶段(timers、pending callbacks、idle/prepare、poll、check、close callbacks),而浏览器没有公开阶段划分,只保证宏/微任务模型一致。最直接影响是:setImmediateprocess.nextTicknode.js 中存在,在浏览器中不存在且不可 polyfill。

立即学习Java免费学习笔记(深入)”;

  • process.nextTick 在当前操作结束、但还没离开当前阶段时执行,优先级高于所有微任务(包括 Promise
  • setImmediate 属于 check 阶段,总在 poll 阶段之后、下次事件循环开始前执行,优先级低于微任务
  • 浏览器里想模拟 process.nextTick,只能用 queueMicrotask,但它不等价——没有更高优先级

真正容易被忽略的是:事件循环本身不“管理”任务队列,它只是按规则消费队列;而队列由 JavaScript 引擎(V8、SpiderMonkey)和宿主环境(chrome、Node.js)共同维护。改写一个 Promise 实现不会改变微任务调度逻辑,但替换掉 setTimeout 的底层绑定,就可能破坏宏任务顺序。

text=ZqhQzanResources