JavaScript定时器基于事件循环异步调度,setTimeout执行一次,setInterval重复执行;两者均不精确,需用clearTimeout/clearInterval清理,避免字符串传参和立即调用函数。

JavaScript 定时器不是“精确钟表”,而是基于事件循环的异步调度机制。它们把回调函数放入任务队列,等主线程空闲时才执行,所以实际延迟可能略大于设定值。
setTimeout:只执行一次的延迟调用
它在指定毫秒数后,将回调函数推入宏任务队列,仅触发一次。适合做延时初始化、防抖、倒计时结束动作等。
- 语法:
setTimeout(callback, delay, ...args)—— 推荐传函数引用,支持直接传参(不用包装函数) - 返回一个定时器 ID,用于后续取消:
clearTimeout(id) - 如果 delay 设为 0,也不会立刻执行,而是“尽快”排到当前任务之后
setInterval:按固定间隔重复执行
它从启动起,每隔指定毫秒就尝试将回调推入宏任务队列,持续运行,直到被手动清除。适合轮询、动画帧模拟、实时状态刷新等。
- 语法:
setInterval(callback, interval, ...args) - 返回定时器 ID,需用
clearInterval(id)停止,否则会一直占用资源 - 注意:若回调执行时间超过 interval,下一次调用不会跳过或累积,而是“尽快”在上一次结束后安排——但可能造成节奏紊乱
关键行为差异
两者都返回数字类型的定时器 ID,但语义和生命周期完全不同:
立即学习“Java免费学习笔记(深入)”;
- 执行次数:setTimeout 仅一次;setInterval 默认无限次
- 清理方式:setTimeout 对应 clearTimeout;setInterval 对应 clearInterval
- 时间精度保障:都不保证绝对准时,但 setTimeout 的延迟偏差通常更可控;setInterval 在回调阻塞时容易“堆积”或“跳帧”
- 替代方案:需要稳定节拍时,可用 setTimeout 递归调用代替 setInterval,便于每次动态调整下一次延迟
常见误用提醒
避免这些写法能减少 Bug:
- 不要传字符串代码(如
setTimeout("func()", 1000)),存在安全与性能问题,已不被推荐 - 不要写
setTimeout(func(), 1000)(带括号),这会立即执行 func 并传回返回值,而非函数本身 - 在组件卸载、页面离开前,务必清除仍在运行的 setInterval,防止内存泄漏或意外触发











