script start → script end → promise then → async end → settimeout,验证同步代码优先执行,随后清空微任务队列(promise.then、async/await 的后续逻辑),最后执行宏任务(settimeout)。

直接用一段包含 同步代码、setTimeout、Promise.then、async/await 的混合脚本,在浏览器控制台运行,观察打印顺序,是最简单有效的测试方式。关键不是“测出来”,而是“看懂每一步为什么在这个时刻执行”。
构造典型测试用例
写一个能暴露宏任务、微任务调度差异的最小可运行片段:
- 开头和结尾放
console.log('script start')和console.log('script end') - 中间插入
setTimeout(..., 0)(宏任务) - 插入一个立即
resolve的Promise,再链式调用.then()(微任务) - 加入一个
async函数调用,内部含await Promise.resolve()
例如:
console.log('script start');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve().then(() => console.log('promise then'));
async function foo() { await Promise.resolve(); console.log('async end'); }
foo();
console.log('script end');
预期输出是:script start → script end → promise then → async end → setTimeout。这个顺序就验证了“同步 → 微任务 → 宏任务”的基本规则。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
用 queueMicrotask 做更精细对比
queueMicrotask 是标准微任务入口,行为和 Promise.then 一致但更轻量,适合做干净对照:
- 它不涉及 Promise 状态管理,纯粹触发一次微任务
- 可以和
Promise.then混用,验证它们是否同属一个队列(结果是:会按添加顺序依次执行) - 比如:
Promise.resolve().then(() => console.log('p'));和queueMicrotask(() => console.log('q'));—— 谁先写谁先执行
避免 Node.js 干扰,统一用浏览器环境
Node.js 的事件循环阶段划分(如 timer、pending callback、idle/prepare 等)比浏览器复杂,且 process.nextTick 优先级高于微任务。前端开发应以浏览器为准:
- 所有测试在 Chrome / Edge / Safari 的 DevTools 控制台中运行
- 不依赖
node --trace-events或perf_hooks - 若需可视化,可用浏览器 Performance 面板录制,筛选 “Event: PromiseResolve” 或 “Timer Fired”
验证 await 的实际暂停点
await 不是“等整个函数结束”,而是等右侧表达式求值后返回的 Promise 被 resolve/reject。测试时注意:
-
await 123等价于await Promise.resolve(123),不产生异步延迟,后续代码仍进微任务 -
await new Promise(r => setTimeout(r, 0))才真正跨宏任务,后续代码会在下一个宏任务开始时执行 - 把
await和setTimeout套在一起,就能清晰看到它如何“让出主线程又回来”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










