javascript中事件循环不执行函数而只调度任务,真正耗时的是函数内同步计算或i/o;需分别测量promise构造器内同步逻辑耗时(用performance.now())及异步操作整体延迟。

在 JavaScript 中,直接“在事件循环中测试异步函数执行耗时”这个说法存在概念混淆——事件循环本身不执行函数,它调度任务(宏任务、微任务);真正耗时的是函数体内的同步计算、I/O 等操作。所以实际要测的是:异步函数内部同步部分的执行时间,以及从发起异步操作到回调/await 完成的整体延迟(含排队、I/O、调度开销)。
一、测异步函数内部同步逻辑耗时(如 Promise 构造器里的代码)
Promise 构造器中的执行器函数(executor)是同步运行的,它的耗时可直接用 performance.now() 测量:
const start = performance.now();
const p = new Promise(resolve => {
// 这里是同步执行的
let sum = 0;
for (let i = 0; i <h3>二、测 await 或 then 回调的实际触发延迟(含事件循环排队)</h3><p>想了解一个 Promise 何时真正被处理(比如 resolve 后多久进入微任务队列并执行),需在回调中再次打点:</p><pre class="brush:php;toolbar:false;">const start = performance.now();
<p>const p = new Promise(resolve => {
setTimeout(() => resolve(), 0); // 模拟异步 resolve
});</p><p>p.then(() => {
const end = performance.now();
console.log('从 new Promise 到 then 执行耗时:', end - start, 'ms');
});</p>注意:这个时间包含 setTimeout 宏任务执行、Promise resolve、微任务入队与执行的全过程,反映真实调度延迟。
三、区分宏任务与微任务的调度差异
用 setTimeout(宏任务)和 Promise.resolve().then(微任务)对比,能观察事件循环阶段的影响:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 微任务总在当前宏任务结束后立即执行,无额外轮次延迟
- setTimeout 即使设为 0,也要等完当前任务 + 所有微任务,再进下一轮宏任务
示例:
const start = performance.now();
<p>setTimeout(() => {
console.log('setTimeout:', performance.now() - start, 'ms');
}, 0);</p><p>Promise.resolve().then(() => {
console.log('Promise.then:', performance.now() - start, 'ms');
});</p><p>// 输出通常类似:
// Promise.then: 0.2 ms
// setTimeout: 0.8 ms(明显更晚)</p>
四、用 Chrome DevTools 精确分析事件循环行为
代码打点只能看粗略时间,深度分析推荐使用浏览器开发者工具:
- 打开 DevTools → Performance 标签 → 点录制 → 执行异步逻辑 → 停止
- 在火焰图中查找
PromiseResolve、TimerFire、FunctionCall等事件 - 查看每个任务的起始/结束时间、是否被延迟(如 “Delayed by X ms” 提示)
- 结合 Event Log 面板,观察宏任务、微任务、渲染帧的交错顺序
这是唯一能看清 V8 如何调度、是否发生任务饥饿或长任务阻塞的方法。
不复杂但容易忽略:异步耗时 ≠ 函数本身执行时间,而是发起时刻到回调执行时刻的端到端延迟,它由代码逻辑、事件循环状态、宿主环境(Node.js 版本 / 浏览器)共同决定。测准的关键是明确你想优化哪一环——是减少同步计算?缩短 I/O?还是降低任务排队?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










