跳转到内容

Javascript计时器

来自代码酷

JavaScript计时器[编辑 | 编辑源代码]

JavaScript计时器是浏览器对象模型(BOM)中用于延迟执行代码或在固定时间间隔重复执行代码的重要功能。它通过setTimeout()setInterval()clearTimeout()/clearInterval()方法实现,是前端开发中处理异步任务的核心工具之一。

计时器类型[编辑 | 编辑源代码]

JavaScript提供两种主要计时器:

1. 一次性计时器(setTimeout)[编辑 | 编辑源代码]

setTimeout()方法在指定延迟后执行代码一次。

// 基本语法
let timerId = setTimeout(function|code, delay[, arg1, arg2...])

参数说明:

  • function|code:要执行的函数或代码字符串(不建议使用字符串形式)
  • delay:延迟时间(毫秒)
  • arg1, arg2...(可选):传递给函数的参数

示例:

function greet(name) {
    console.log(`Hello, ${name}!`);
}

// 3秒后执行
setTimeout(greet, 3000, "Alice");

// 输出:
// (3秒后) Hello, Alice!

2. 间隔计时器(setInterval)[编辑 | 编辑源代码]

setInterval()方法按固定时间间隔重复执行代码。

// 基本语法
let timerId = setInterval(function|code, delay[, arg1, arg2...])

示例:

let counter = 0;
const maxCount = 5;

function countUp() {
    console.log(`Count: ${++counter}`);
    if (counter >= maxCount) {
        clearInterval(intervalId);
    }
}

// 每1秒执行一次
const intervalId = setInterval(countUp, 1000);

/* 输出:
Count: 1
(1秒后) Count: 2
...
(4秒后) Count: 5
*/

清除计时器[编辑 | 编辑源代码]

使用clearTimeout()clearInterval()可以取消尚未执行的计时器。

示例:

const timerId = setTimeout(() => {
    console.log("这行不会执行");
}, 2000);

// 取消计时器
clearTimeout(timerId);

计时器工作原理[编辑 | 编辑源代码]

JavaScript计时器基于事件循环机制工作:

graph TD A[调用setTimeout/setInterval] --> B[Web API计时器] B --> C{事件循环检查} C -->|时间到达| D[回调进入任务队列] D --> E[调用栈空闲时执行]

重要特性:

  • 计时器不保证精确时间,受主线程阻塞影响
  • 最小延迟在嵌套调用时为4ms(HTML5规范)
  • 延迟0ms不等于立即执行

高级用法[编辑 | 编辑源代码]

递归setTimeout[编辑 | 编辑源代码]

setInterval更精确的重复执行方式:

function repeat() {
    console.log(new Date().toLocaleTimeString());
    setTimeout(repeat, 1000);
}

setTimeout(repeat, 1000);

性能考虑[编辑 | 编辑源代码]

  • 避免频繁短间隔计时器(<100ms)
  • 不活动标签页可能限制最小间隔(通常1秒)
  • 使用requestAnimationFrame处理动画

实际应用案例[编辑 | 编辑源代码]

1. 倒计时功能[编辑 | 编辑源代码]

function startCountdown(seconds) {
    let remaining = seconds;
    
    const countdown = setInterval(() => {
        console.log(`剩余时间: ${remaining--}秒`);
        if (remaining < 0) {
            clearInterval(countdown);
            console.log("时间到!");
        }
    }, 1000);
}

startCountdown(5);

/* 输出:
剩余时间: 5秒
剩余时间: 4秒
...
剩余时间: 0秒
时间到!
*/

2. 输入防抖(Debounce)[编辑 | 编辑源代码]

function debounce(func, delay) {
    let timerId;
    
    return function(...args) {
        clearTimeout(timerId);
        timerId = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    };
}

// 使用示例
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function() {
    console.log('发送搜索请求:', this.value);
}, 500));

数学原理[编辑 | 编辑源代码]

计时器误差可以用公式表示:

解析失败 (语法错误): {\displaystyle 误差 = 实际执行时间 - 预期延迟时间 }

当存在嵌套调用时,HTML5规范定义的最小延迟:

解析失败 (语法错误): {\displaystyle 嵌套层级 ≥ 5 \Rightarrow 最小延迟 = 4ms }

常见问题[编辑 | 编辑源代码]

Q: 为什么我的计时器不精确? A: 因为JavaScript是单线程的,长时间运行的任务会阻塞计时器回调的执行。

Q: setTimeout(fn, 0)有什么用途? A: 用于将代码推迟到当前执行栈清空后执行,常用于异步操作。

Q: 如何实现精确计时? A: 考虑使用Web Worker或performance.now()进行补偿计算。

浏览器兼容性[编辑 | 编辑源代码]

所有现代浏览器完全支持计时器API,包括:

  • Chrome 1+
  • Firefox 1+
  • Safari 1+
  • Edge 12+
  • Internet Explorer 4+

最佳实践[编辑 | 编辑源代码]

1. 总是清除不再需要的计时器 2. 避免在计时器中修改DOM(使用requestAnimationFrame) 3. 对于复杂动画考虑使用CSS动画/过渡 4. 在页面不可见时(通过Page Visibility API)暂停非必要计时器

通过掌握JavaScript计时器,您可以创建响应式、动态的网页应用,处理各种时间相关的任务和动画效果。