JavaScript篇:前端定时器黑科技:不用setInterval照样玩转循环任务

大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

技术qq交流群:906392632

大家好,我是小杨,一个干了快6年的前端老司机。今天要和大家分享一个特别实用的定时器技巧------用setTimeout实现setInterval。这个方案不仅能解决setInterval的一些痛点,还能让我们的定时任务更加可控。

一、为什么不用setInterval?

先说说我为什么研究这个方案。去年在做一个大屏数据实时刷新功能时,发现直接用setInterval会有个恶心的问题:

javascript 复制代码
setInterval(() => {
  // 模拟网络请求
  console.log('执行任务', new Date().getSeconds());
}, 1000);

看起来每1秒执行一次对吧?但如果网络卡顿导致函数执行超过1秒呢?这时候就会发现多个任务挤在一起执行,就像早高峰的地铁一样让人崩溃。

二、setTimeout的救场方案

后来我改用setTimeout递归调用的方式,完美解决了这个问题:

javascript 复制代码
function 我的循环任务() {
  console.log('执行任务', new Date().getSeconds());
  
  // 在函数末尾重新调用自己
  setTimeout(我的循环任务, 1000);
}

// 启动任务
setTimeout(我的循环任务, 1000);

这个方案的精妙之处在于:每次都是等上次任务完全执行完,才重新计时。就像排队上厕所,必须等前一个人出来,下个人才能进去。

三、升级版:可控定时器

后来我又做了个加强版,加上了启动/停止功能:

javascript 复制代码
let timer = null;
let count = 0;

function 我的可中断任务() {
  console.log(`执行第${++count}次`, new Date().getSeconds());
  
  if(count < 5) { // 只执行5次
    timer = setTimeout(我的可中断任务, 1000);
  }
}

// 启动
timer = setTimeout(我的可中断任务, 1000);

// 随时可以停止
// clearTimeout(timer);

这样写有三个好处:

  1. 避免任务堆积
  2. 可以精确控制执行次数
  3. 随时能终止任务

四、实战中的应用场景

这个技巧在我工作中帮了大忙,比如:

  1. 轮询接口:检查订单状态,直到支付成功
  2. 动画序列:实现复杂的多段动画效果
  3. 倒计时:更精准的秒表功能
javascript 复制代码
// 倒计时示例
function 倒计时(剩余秒数) {
  console.log(`剩余:${剩余秒数}秒`);
  
  if(剩余秒数 > 0) {
    setTimeout(() => 倒计时(剩余秒数 - 1), 1000);
  }
}

倒计时(10); // 开始10秒倒计时

五、注意事项

虽然这个方案很香,但也要注意:

  1. 记得保存timer变量,否则没法清除
  2. 递归调用要注意停止条件,避免内存泄漏
  3. 长时间运行的任务可能会造成调用栈过深

六、总结

setTimeout实现setInterval的方案,就像是用乐高积木拼出了现成玩具的功能,虽然多写几行代码,但获得了更大的灵活性和可控性。特别适合需要精确控制执行时机的场景。

大家如果有更好的实现方案,欢迎在评论区交流~如果觉得有用,别忘了点赞收藏!

相关推荐
还有几根头发呀36 分钟前
UDP 与 TCP 调用接口的差异:面试高频问题解析与实战总结
网络·网络协议·tcp/ip·面试·udp
Dontla3 小时前
为什么React列表项需要key?(React key)(稳定的唯一标识key有助于React虚拟DOM优化重绘大型列表)
javascript·react.js·ecmascript
EndingCoder4 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
阿阳微客5 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
德育处主任Pro5 小时前
『React』Fragment的用法及简写形式
前端·javascript·react.js
CodeBlossom6 小时前
javaweb -html -CSS
前端·javascript·html
CodeCraft Studio6 小时前
【案例分享】如何借助JS UI组件库DHTMLX Suite构建高效物联网IIoT平台
javascript·物联网·ui
打小就很皮...6 小时前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡7 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜058 小时前
React - 组件通信
前端·react.js·前端框架