LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

不是吧!定时器你还在用 setInterval?90% 的前端都踩过的坑,今天一次性根治!

freeflydom
2025年3月18日 9:35 本文热度 480

这是全网唯一敢说真话的定时器解析,看完直接扔掉 setInterval,从此告别卡顿、延迟、内存泄漏!

作为前端工程师,定时任务谁没写过?但如果你还在用 setInterval,甚至用第三方库管理定时器——恭喜你,成功为项目埋下了一颗定时炸弹💣。

我见过太多工作 3 年以上的程序员,还在用 setInterval(fn, 100) 做轮询请求,结果页面越用越卡,最后直接白屏。不是浏览器不行,是你写法太骚啊!

今天我要用 3 个颠覆认知的骚操作,让你彻底掌握定时器的正确打开方式。文末附手写 防崩溃版 setInterval 源码,直接抄作业!


一、血泪教训:setInterval 的三大致命伤

1. 误差累积陷阱

你以为下面代码每秒精准执行?

setInterval(() => {
  console.log('Hi!');
}, 1000);

错!  当回调函数执行时间超过间隔时,下次执行会立即触发,导致误差累积:

(执行时间超过间隔时引发的连环车祸)

2. 内存泄漏鬼才

以下代码有什么问题?

let data = fetchBigData(); // 获取超大数据
setInterval(() => {
  processData(data); 
}, 1000);

data 永远无法被垃圾回收!  因为闭包持有 data 引用,即使组件卸载,定时器仍在后台运行。

3. 主线程卡顿

当页面有复杂计算时,setInterval 的回调会排队等待,出现跳帧现象

(主线程阻塞导致定时器回调延迟执行)


二、究极解决方案:用 setTimeout 手搓高性能定时器

🌰 对比实验:递归 vs 普通 setTimeout

普通版(错误示范❌):

function task() {
  console.log('执行');
  setTimeout(task, 1000); // 下次执行在 1 秒后
}
task();

防崩版(正确姿势✅):

function customInterval(callback, delay) {
  let start = Date.now();
  let count = 0;
  
  function loop() {
    const current = Date.now();
    const elapsed = current - start;
    const targetNextTime = ++count * delay;
    // 计算下次执行的时间偏差
    const deviation = targetNextTime - elapsed;
    const nextDelay = Math.max(0, delay - deviation);
    setTimeout(() => {
      callback();
      loop();
    }, nextDelay);
  }
  loop();
}
// 使用
customInterval(() => {
  console.log('精准执行!');
}, 1000);

核心原理:

  • 动态计算时间偏差(deviation
  • 通过 nextDelay 自动修正延迟
  • 误差控制在 ±1ms 内,吊打原生 setInterval

三、进阶骚操作:Web Worker + AbortController

1. 主线程零阻塞

将定时任务交给 Web Worker:

// main.js
const worker = new Worker('timer-worker.js');
worker.postMessage({ type: 'start', delay: 1000 });
// timer-worker.js
self.addEventListener('message', (e) => {
  if (e.data.type === 'start') {
    setInterval(() => {
      self.postMessage('tick');
    }, e.data.delay);
  }
});
2. 优雅清除定时器

下面实现定时关闭:

      //定时器的手写
    function customSetTimeout(fn,time){
        let timer = null;
        function loop(){
            timer = setTimeout(() => {
                fn();
                loop();
            },time)
        }
        loop();
        return () => clearTimeout(timer);
    }
    // 使用定时器,要做什么任务
   const tt=  customSetTimeout(() => {
        console.log("11111");
    },1000);
    // 10s 后关闭任务,运行9次
    setTimeout(() => {
        tt();
    },10000);

四、总结与灵魂拷问

三个必背知识点:

  1. setInterval 误差会累积,递归 setTimeout 才是王道
  2. 定时器必须配合清除逻辑,否则内存泄漏分分钟
  3. 复杂任务请交给 Web Worker,别折磨主线程

转自https://juejin.cn/post/7481909735869235263


该文章在 2025/3/18 9:37:54 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved