返回知识库

工程与栈 · 开发基础

JavaScriptJavaScript

网页的脚本语言按事件循环跑:同步代码先改页面,再清空微任务,最后才取宏任务——setTimeout(0) 不会立刻执行。

先认出这张商店页,再决定更新何时发生

下面就是会响应点击的商品卡:默认购物车是 0。点「立刻改数量」,数字变成 1;再试把更新丢进 setTimeout(0),失败也写在同一张卡上。

檐下咖啡 · 今日豆未加入 · 数量 0

手冲今日豆

¥42 · 同步先改数量,再清微任务,最后才轮到 setTimeout。

购物车0

未加入 · 数量 0数量长在商品卡上。

原因:同步代码会立刻改页面。下一步:点「立刻改数量」,或试「丢进 setTimeout(0)」看数量会不会卡住。

知识点:同步先、微任务次、宏任务最后

购物车数字已经演示了顺序,这里只命名三层。

  • 同步代码一口气跑完:直接改数量、console.log,不会被回调插队。
  • 微任务在下一个宏任务之前清空:Promise.then 会补上「库存已锁」。
  • 宏任务一次只取一个:setTimeout 即使写 0,也排在最后,插不进微任务前面。
  • 离开后要盯:看见 setTimeout 与 Promise 混用,先归类再按这个顺序排。

什么时候用、怎么用

回调、延迟、异步混在一起时,用事件循环顺序判断;纯同步从上到下即可。

  • 信号:点了按钮数量没变、setTimeout(fn, 0) 以为马上跑、Promise 和定时器抢顺序。
  • 适用:预测输出顺序、排查「数据明明在却读到 undefined」。
  • 不适用:CPU 密集任务卡住主线程,要拆任务或用 Worker,不是调顺序能解决。
  • 最短路径:把每行标成同步 / 微任务 / 宏任务 → 先写同步结果 → 再清空微任务 → 最后宏任务。

正反例:同一下「加入购物车」

目标都是让数量变成 1,只改更新写在哪。

正例同步改 count,再让 Promise 收尾

页面立刻显示 1,顺序可预测。结果长在购物车数字上。

反例把改数量塞进 setTimeout(fn, 0)

以为 0 毫秒就是马上,数量还停在 0。失败写在商品卡上。

快速自测

console.log("A"); setTimeout(() => console.log("B"), 0); Promise.resolve().then(() => console.log("C")); console.log("D"); 输出顺序是?

继续查证

术语的技术定义和行为以这些一手或权威资料为准。

下一步学

和本知识点经常一起出现的概念。