news 2026/4/29 13:54:45

JavaScript 定时器完全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript 定时器完全攻略

一、前言

在 JavaScript 中,定时器是实现延迟执行代码、周期性执行代码的核心工具,广泛应用于轮播图、倒计时、定时刷新数据等场景。本文将全面梳理 JS 定时器的核心用法、区别、注意事项及实战技巧,适合前端初学者巩固基础,也可作为开发中的参考手册。

二、JS 定时器的两种核心类型

JavaScript 提供了两种原生定时器方法,均挂载在window对象上(浏览器环境),无需额外引入依赖即可使用。

一次性定时器:setTimeout ()

延迟指定时间后,只执行一次指定的回调函数(或代码片段)。

// 语法1:传入回调函数lettimeoutId=setTimeout(callback,delay,[param1,param2,...]);

参数说明:

  • callback:必需,延迟后要执行的回调函数(无返回值)。

  • delay:可选,延迟时间,单位为毫秒(ms),默认值为0(注意:不是立即执行,后续会解释)。

  • [param1, param2, …]:可选,传递给回调函数的参数列表。

  • timeoutId:返回值,定时器的唯一标识(正整数),用于后续取消定时器。

周期性定时器:setInterval ()

每隔指定时间,重复执行指定的回调函数(或代码片段),直到主动取消或页面卸载。

letintervalId=setInterval(函数,时间)
  • 第一个参数传函数名,第二个参数是间隔时间,毫秒为单位

  • intervalId:返回值,定时器的唯一标识(正整数),用于后续取消定时器。

三、取消定时器:清除已创建的定时器

定时器创建后,可通过其返回的唯一标识(timeoutId/intervalId)取消执行,避免不必要的性能消耗。

  • 取消一次性定时器:clearTimeout(timeoutId)
  • 取消周期性定时器:clearInterval(intervalId)
letn=setInterval(function(){i--btn.innerHTML=`我已经阅读用户协议(${i})`if(i===0){clearInterval(n)btn.disabled=falsebtn.innerHTML=`同意`}},1000)

已取消的定时器标识无法再复用,若需重新执行定时器,需重新调用setTimeout()/setInterval()并获取新标识。

四、关键理解:定时器的延迟时间不是绝对的

很多初学者会疑惑:为什么设置delay=1000,但函数不是恰好 1 秒后执行?
核心原因:JavaScript 是单线程语言,定时器的回调函数需要等待主线程空闲后才能执行。

  1. 当调用setTimeout()/setInterval()时,JS 引擎会将定时器回调函数放入定时器队列,并开始计时。
  2. 当delay时间到达后,回调函数并不会立即执行,而是会被移入任务队列(宏任务队列)。
  3. JS 主线程遵循 “事件循环(Event Loop)” 机制,只有当主线程当前的同步代码执行完毕,且任务队列中没有其他更早的宏任务时,才会从任务队列中取出回调函数执行。
  4. 因此,若主线程被耗时的同步代码(如复杂循环、大型计算)阻塞,回调函数的执行时间会大于等于delay设定的时间。

五、setInterval () 的潜在问题:回调执行重叠(及解决方案)

  • 潜在问题:回调执行重叠
    setInterval()的设计缺陷:它会按照固定的时间间隔将回调函数推入任务队列,不关心上一次的回调函数是否已经执行完毕。
  • 若上一次回调函数执行耗时超过delay设定的时间间隔,下一次回调函数已经被推入任务队列,会导致多个回调函数连续执行(即 “执行重叠”)。
  • 长期运行可能导致内存泄漏、页面卡顿,尤其在处理网络请求、DOM 操作等耗时操作时风险更高。

2.解决方案:嵌套 setTimeout () 实现可靠的周期性执行

  • 通过在setTimeout()的回调函数中重新调用自身,实现周期性执行,优势是确保上一次回调函数完全执行完毕后,再开始下一次计时,避免执行重叠。
// 嵌套setTimeout()实现周期性执行(推荐)functionperiodicTask(){// 1. 执行核心业务逻辑letnow=newDate().toLocaleTimeString();console.log("当前时间:",now);// 2. 上一次任务执行完毕后,延迟1秒再开启下一次任务setTimeout(periodicTask,1000);}// 启动周期性任务periodicTask();// 如需取消,可保存定时器标识并调用clearTimeout()lettaskId;functioncancelPeriodicTask(){clearTimeout(taskId);console.log("周期性任务已取消");}

相比setInterval(),嵌套setTimeout()的执行间隔是 “上一次任务结束到下一次任务开始” 的间隔,更可控。
避免了回调重叠问题,适合执行耗时不确定的周期性任务(如定时请求接口获取数据)。
核心作用

  • 实现 “异步执行”,将耗时较短的任务推迟到同步代码执行完毕后执行,避免阻塞主线程。
  • 常用于调整代码执行顺序,例如:优先执行同步 DOM 操作,再执行后续的逻辑处理。

六、总结

  1. JS 定时器有两种核心类型:一次性setTimeout()(只执行一次)、周期性setInterval()(重复执行)。
  2. 取消定时器对应clearTimeout()和clearInterval(),需依赖定时器返回的唯一标识。
  3. 定时器的延迟时间是 “最小延迟”,而非 “绝对延迟”,受单线程事件循环机制影响。
  4. setInterval()存在回调重叠风险,推荐使用嵌套setTimeout()实现可靠的周期性执行。
  5. setTimeout(callback, 0)用于将任务推迟到同步代码执行完毕后执行,实现异步插队。
  6. 开发中需注意及时清除定时器、处理this指向、避免传入字符串回调等避坑点。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 3:44:43

法律大模型实战指南:LLM智能体如何破解法律AI三大难题

本文全面综述法律领域LLM智能体技术,分析其如何通过规划、记忆和工具调用能力解决独立模型面临的幻觉、信息滞后及可验证性不足等挑战。文章系统梳理技术转型路径,构建法律智能体应用分类体系,探讨专门评估方法,并识别开放性挑战&…

作者头像 李华
网站建设 2026/4/26 21:41:19

基于GPU加速的大数据OLAP查询优化实践

基于GPU加速的大数据OLAP查询优化实践:从原理到落地的全流程指南 一、引言:当OLAP遇到“速度瓶颈”——你经历过吗? 1.1 一个真实的痛点:大促后的“查询焦虑症” 去年双11大促结束后,我在电商公司的分析师朋友小张遇到…

作者头像 李华
网站建设 2026/4/27 6:55:36

一文搞懂大模型剪枝

一、什么是大模型剪枝? 通俗来讲,大模型剪枝就是识别并移除模型中“没用”或“用处极小”的部分,这些被移除的部分就是模型的“冗余成分”。 我们可以把大模型想象成一个精密的工厂,里面有无数条生产线(对应模型的层、…

作者头像 李华