setTimeout只执行一次,setInterval反复执行直至手动清除;前者是延迟一次的宏任务,后者是按间隔触发但易堆积回调,误用会导致内存泄漏或UI卡顿。
setTimeout 只执行一次,setInterval 会反复执行,直到被手动清除。 这不是语义差别,而是底层行为和调度逻辑的根本不同——选错就可能造成内存泄漏、回调堆积或 UI 卡顿。
它把回调函数推入宏任务队列,等待至少指定毫秒后执行,且只执行一回。即使主线程卡住(比如跑了个 200ms 的 for 循环),实际执行时间也会被推迟,但不会补发。
4ms(即使写 0)clearTimeout(id) 才能取消setTimeout(greet, 1000, "Alice"),比拼字符串更安全let timer = setTimeout(() => {
console.log("只出现一次");
}, 1000);
// 后续想取消?得保留 timer 变量并调用:
/
/ clearTimeout(timer);
它尝试每 delay 毫秒执行一次回调,但前提是上一次回调已结束。如果回调耗时 > delay(比如接口慢、渲染重),下一次就会立刻执行,形成“回调堆积”,看起来像“突然连刷好几条”。
clearInterval(id)
setTimeout 递归代替let count = 0;
const interval = setInterval(() => {
count++;
console.log(`第 ${count} 次`);
if (count >= 3) clearInterval(interval); // 必须主动停
}, 1000);
不是“重复就用 setInterval”,而是看逻辑是否天然具备终止条件或是否允许误差累积。
setTimeout + clearTimeout,每次新输入就重置计时器setTimeout 递归(setTimeout(fn, 1000) 里再调自己),避免 setInterval 堆积导致跳秒setInterval 更直观,但务必加超时控制和错误兜底(比如连续失败 3 次就停)setTimeout(fn, 0),靠它把任务塞进下一个宏任务,确保 DOM 已更新最常被忽略的一点:setInterval 的“间隔”是两次 开始执行 的时间差,不是两次 执行完成 的间隔。一旦回调变慢,整个节奏就崩了——这不是 bug,是设计使然。真要稳,就别贪方便,老实用 setTimeout 串起来。