核心是防止任务堆积,应改用 setTimeout 递归替代 setInterval,并配合执行锁与时间校准;禁用同步阻塞操作,组件卸载时必须清除定时器。

核心是不让任务“堆起来”——setInterval 本身不卡,卡的是它不管前一次是否结束就强行发车。真正的问题在于执行逻辑没控制好,而不是定时器本身。
用 setTimeout 递归替代 setInterval
这是最直接、最有效的解法。让下一次执行严格等在上一次完成之后,彻底切断堆积链路。
- 写法简单:不调用 setInterval,改用 setTimeout 自调用
- 示例:
let timer = null;<br>const tick = () => {<br> this.fetchData(); // 或其他耗时操作<br> timer = setTimeout(tick, 1000);<br>};<br>timer = setTimeout(tick, 1000); - 天然防堆积,还能根据实际耗时动态调整下次延迟(比如接口返回慢了,就延长下一次间隔)
加执行锁 + 时间校准(适合轮询场景)
当业务要求“至少间隔 X 毫秒”,但绝不允许重叠执行时,仅靠 setTimeout 递归可能间隔偏长,这时需主动控制最小间隔。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 定义状态标志:
this.isRunning = false - 每次进入回调先判断:
if (this.isRunning) return; - 执行前设为 true,结束后设为 false,并用
performance.now()记录起始时间,确保两次真实执行间隔 ≥ 设定值 - 适用于轮询接口、防重复提交等对节奏有底线要求的场景
避免在回调里做同步阻塞操作
耗时任务本身才是卡顿源头,定时器只是暴露问题的放大器。
立即学习“Java免费学习笔记(深入)”;
- 禁止在 setInterval 或 setTimeout 回调中使用同步 AJAX(如
XMLHttpRequest.open(..., false)),这会直接冻结主线程 - 大量计算或 DOM 操作应拆分、分片或移至 Web Worker
- 频繁更新响应式数据(如 Vue 中反复赋值)会触发多次 patch,建议批量合并或用 computed 缓存
组件卸载时必须清除定时器
这不是可选项,是防止内存泄漏的硬性要求。
- Vue 2 在
beforeDestroy,Vue 3 在onBeforeUnmount中调用clearTimeout或clearInterval - 建议统一管理所有定时器 ID(例如存在数组里),销毁时遍历清除,避免漏掉
- 漏掉这一步,闭包会持续持有组件实例,导致数据、DOM 节点无法回收

















