1. 定时器基础:认识JavaScript的时间管理者
JavaScript定时器是前端开发中最基础却最容易踩坑的功能之一。我至今还记得刚入行时,因为不理解定时器的工作原理,导致页面动画卡顿被项目经理当众批评的场景。定时器看似简单,但想要真正掌握它,需要理解浏览器的事件循环机制。
所有JavaScript定时器本质上都是通过浏览器提供的Web API实现的。当我们调用setTimeout或setInterval时,实际上是在告诉浏览器:"在指定的时间后,把这个回调函数放入任务队列"。这里有个关键点要明白:定时器指定的时间并不是精确的执行时间,而是"最早可执行时间"。
1.1 setTimeout基础用法
最基本的定时器是setTimeout,它的语法非常简单:
javascript复制const timerId = setTimeout(callback, delay, arg1, arg2...)
这个简单的API背后有几个重要细节:
- delay参数的单位是毫秒(ms),但实际延迟可能会更长
- 回调函数可以接收额外的参数(arg1, arg2等)
- 返回值是一个数字ID,用于后续清除定时器
一个常见的误解是认为delay参数是精确的。实际上,由于JavaScript的单线程特性,定时器回调只能在主线程空闲时执行。如果主线程被长时间运行的代码阻塞,定时器回调就会被延迟执行。
1.2 setInterval的循环魔法
与setTimeout不同,setInterval会重复执行回调函数:
javascript复制const intervalId = setInterval(callback, delay, arg1, arg2...)
这里有个重要特性:setInterval会固定时间间隔将回调放入队列,而不管前一个回调是否已经执行完成。这意味着如果回调执行时间超过了间隔时间,多个回调可能会连续快速执行,导致性能问题。
我在实际项目中就遇到过这种情况:一个复杂的动画回调执行需要200ms,但间隔设置为100ms,结果页面很快就卡死了。解决方案要么是增加间隔时间,要么改用链式setTimeout:
javascript复制function run() {
// 执行任务
setT
