setTimeout(fn, delay) 在 delay 毫秒后把回调推入宏任务队列,只执行一次;setInterval(fn, delay) 则每隔 delay 重复执行。注意 delay 的真实语义是「至少等这么久」——它是任务队列的入队时机,如果主线程被长任务阻塞,回调会推迟更久,setInterval 还可能因前一次回调没跑完而出现堆积。
工程实践上能用 setTimeout 就别用 setInterval:间隔不精确、清理麻烦(clearInterval 要保存 id)、页面切到后台定时器会被限流节流。循环场景统一用 setTimeout 递归自调用——下一次调度由上一次回调触发,自然避开堆积问题。清理用 clearTimeout/clearInterval(两者已可混用),组件卸载或路由切换时务必清理,否则回调里访问已销毁的 DOM 就报错。
// setTimeout:延迟一次 const t1 = setTimeout(() => { console.log('2 秒后执行一次'); }, 2000); clearTimeout(t1); // 取消则不会执行 // setInterval 与清理 let count = 0; const timer = setInterval(() => { count += 1; console.log('第 ' + count + ' 次'); if (count >= 3) clearInterval(timer); // 达到 3 次停止 }, 500); //推荐的递归 setTimeout 写法:间隔更稳、不堆积 let n = 0; function tick() { n += 1; console.log('tick ' + n); if (n < 3) setTimeout(tick, 500); } setTimeout(tick, 500);