定时器与间歇函数

1. setInterval():周期性执行函数

setInterval() 会按照指定的时间间隔(毫秒)重复执行一个函数,直到被手动停止。

基本语法:
javascript 复制代码
const intervalId = setInterval(callback, delay, [arg1, arg2, ...]);
  • callback:要执行的函数。
  • delay:每次执行的间隔时间(毫秒)。
  • arg1, arg2, ... :可选参数,传递给 callback 的参数。
示例:每秒更新时钟
javascript 复制代码
function updateClock() {
  const now = new Date();
  console.log(now.toLocaleTimeString());
}

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

// 5秒后停止
setTimeout(() => {
  clearInterval(intervalId); // 清除定时器
}, 5000);

2. setTimeout():延迟执行函数

setTimeout() 会在指定的延迟时间(毫秒)后执行一次函数。

基本语法:
javascript 复制代码
const timeoutId = setTimeout(callback, delay, [arg1, arg2, ...]);

参数含义与 setInterval() 相同。

示例:延迟提示
javascript 复制代码
function showMessage() {
  alert('3秒后显示此消息');
}

// 3000毫秒(3秒)后执行
setTimeout(showMessage, 3000);

3. 清除定时器

为避免内存泄漏或不必要的执行,需要在适当的时候清除定时器:

清除 setInterval()
javascript 复制代码
const intervalId = setInterval(() => { /* 代码 */ }, 1000);
clearInterval(intervalId); // 停止循环执行
清除 setTimeout()
javascript 复制代码
const timeoutId = setTimeout(() => { /* 代码 */ }, 1000);
clearTimeout(timeoutId); // 取消延迟执行

4. 应用场景

(1)轮询数据

定期从服务器获取更新:

javascript 复制代码
function fetchData() {
  fetch('/api/data')
    .then(response => response.json())
    .then(data => console.log(data));
}

// 每5秒请求一次
setInterval(fetchData, 5000);
(2)实现动画效果

通过微小间隔更新元素样式:

javascript 复制代码
const element = document.getElementById('box');
let position = 0;

function move() {
  position += 1;
  element.style.left = `${position}px`;
}

// 每16毫秒(约60FPS)更新一次位置
setInterval(move, 16);
(3)延迟加载资源
javascript 复制代码
// 页面加载后3秒加载广告脚本
setTimeout(() => {
  const script = document.createElement('script');
  script.src = 'ad.js';
  document.body.appendChild(script);
}, 3000);

5. 注意事项

(1)时间精度问题
  • JavaScript 是单线程的,定时器的执行时间可能会受到其他任务的影响,实际延迟可能比设定值长。
(2)闭包陷阱
  • 定时器中的回调函数会捕获外部变量,可能导致意外结果:

    javascript 复制代码
    for (var i = 0; i < 5; i++) {
      setTimeout(() => {
        console.log(i); // 输出5,5,5,5,5
      }, 1000);
    }
    
    // 使用let(块级作用域)或立即执行函数解决
    for (let i = 0; i < 5; i++) {
      setTimeout(() => {
        console.log(i); // 输出0,1,2,3,4
      }, 1000);
    }
(3)内存泄漏风险
  • 未清除的定时器会持续占用内存,特别是在单页应用(SPA)中切换页面时。

6. 替代方案

(1)requestAnimationFrame()

更适合高性能动画,由浏览器优化执行时机:

javascript 复制代码
function animate() {
  // 更新动画
  requestAnimationFrame(animate); // 递归调用
}

requestAnimationFrame(animate);
(2)Promise + setTimeout

实现可暂停、可链式调用的延迟:

javascript 复制代码
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 使用示例
async function fetchWithRetry() {
  try {
    const response = await fetch('/api/data');
    return response.json();
  } catch (error) {
    await delay(2000); // 等待2秒后重试
    return fetchWithRetry();
  }
}
相关推荐
_F_y4 小时前
MySQL用C/C++连接
c语言·c++·mysql
会跑的葫芦怪4 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
pengdott4 小时前
Oracle RAC内存融合技术深度解析:集群性能的幕后引擎
数据库·oracle
微露清风5 小时前
系统性学习Linux-第二讲-基础开发工具
linux·运维·学习
xiaoqi9225 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233225 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
阳光九叶草LXGZXJ5 小时前
达梦数据库-学习-48-DmDrs控制台命令(同步之Manager、CPT模块)
linux·运维·数据库·sql·学习
五岳6 小时前
DTS按业务场景批量迁移阿里云MySQL库实战(上):技术选型和API对接
mysql·阿里云·dts
我科绝伦(Huanhuan Zhou)6 小时前
脚本再升级,兼容Oracle 26ai一键安装
数据库·oracle
biuyyyxxx6 小时前
Python自动化办公学习笔记(一) 工具安装&教程
笔记·python·学习·自动化