setInterval,setTimeout 2种计时器在同一个页面处理任务,想看下精度用时情况。


setInterval的任务正在执行时,setTimeout的任务会等待前者完成后再执行,这样会造成2个计时器的时间精度出错?本来settimeout启动0.5秒,执行2秒,每次2.5秒精确,因为用了setInterval,会造成浪费更多时间?

已完成思考

在 JavaScript 中,由于单线程事件循环的特性,setInterval 和 setTimeout 的时间精度确实会受到任务执行时长和其他任务阻塞的影响,尤其是当存在长时间运行的任务时,两者的行为差异和相互干扰会导致时间精度进一步下降,甚至出现 “浪费时间” 的现象。下面结合你的场景具体分析:

一、单线程机制:定时器精度的 “先天限制”

JavaScript 是单线程的,所有任务(包括定时器回调、事件处理等)都需要在同一个主线程中排队执行。当一个任务正在执行时,其他任务必须进入事件队列等待,直到当前任务完成后才能被执行。这意味着:
定时器的 “预期触发时间” 只是 “最早可能执行时间”,而非 “精确执行时间”。如果此时主线程被其他任务占用(比如你的场景中每次任务需要执行 2 秒),定时器回调会被延迟到主线程空闲后才执行,导致实际执行时间比预期晚。

二、setInterval 的 “无防堆积” 特性:精度问题的放大器

你的场景中 setInterval 被设置为每 0.5 秒触发一次,而任务本身需要执行 2 秒(远长于间隔时间)。setInterval 的核心特性是:它的时间间隔是从 “上一次触发时刻” 开始计算的,而非 “上一次执行完成时刻”。这会导致严重的任务堆积问题:

  • 预期行为:每 0.5 秒触发一次,每次执行 2 秒。
  • 实际行为
    第 1 次触发后,任务开始执行(耗时 2 秒);
    0.5 秒后(第 0.5 秒),setInterval 会强制添加第 2 次任务到队列(即使第 1 次还在执行);
    又过 0.5 秒(第 1.0 秒),添加第 3 次任务到队列;
    以此类推,直到第 1 次任务在第 2 秒完成后,队列中堆积的第 2、3、4 次任务会 “连续执行”,导致实际触发间隔完全混乱,且总耗时远超过预期。

这种 “无防堆积” 的特性会让 setInterval 的时间精度极差 —— 它不关心前一次任务是否完成,只会机械地按固定间隔添加任务,最终导致任务 “扎堆执行”,实际间隔和预期间隔完全脱节。

三、setTimeout 递归调用:相对更可控的精度

如果用 setTimeout 递归实现(即每次任务完成后,再通过 setTimeout 安排下一次任务),行为会更可控:

  • 逻辑:第 1 次任务执行完成后(耗时 2 秒),通过 setTimeout 延迟 0.5 秒触发第 2 次任务,以此类推。
  • 实际间隔:每次任务的 “实际间隔” 是 “任务执行时间(2 秒)+ 延迟时间(0.5 秒)”,总间隔稳定在 2.5 秒左右(理想状态下)。

这是因为 setTimeout 递归的间隔是从 “上一次任务完成时刻” 开始计算的,不会像 setInterval 那样在任务执行期间堆积新任务。但注意:如果存在其他任务(比如 setInterval 的任务)阻塞主线程,setTimeout 的回调同样会被延迟,导致实际间隔变长。

四、两者同时运行:相互阻塞导致精度 “雪上加霜”

当 setInterval(无防堆积)和 setTimeout 同时调用同一个耗时 2 秒的任务时,由于单线程限制,它们的回调会在事件队列中排队,互相阻塞,导致:

  1. setInterval 的堆积任务抢占资源
    setInterval 每 0.5 秒添加一个任务到队列,即使前一个任务还在执行。这些堆积的任务会占用主线程,导致 setTimeout 的回调被延迟更久。例如:

    • setTimeout 预期 0.5 秒后执行,但此时队列中可能有 setInterval 堆积的 3 个任务(每个 2 秒),setTimeout 的回调需要等待 3×2=6 秒后才能执行,实际间隔变成 6.5 秒,完全偏离预期。
  2. setTimeout 的长任务反堵 setInterval
    反过来,setTimeout 的 2 秒任务执行时,setInterval 仍在按 0.5 秒间隔添加新任务到队列,导致 setInterval 的任务堆积更多,进一步加剧主线程阻塞。

  3. 总耗时大幅增加
    原本 setTimeout 递归单独运行时,4 次任务总耗时约 4×2.5=10 秒(理想状态);但如果和 setInterval 同时运行,由于任务排队阻塞,总耗时可能远超 10 秒,且两者的实际执行次数和时间间隔都会变得混乱。

五、为什么会 “浪费更多时间”?

“浪费时间” 本质上是任务阻塞导致的等待时间。在你的场景中:

  • setInterval 的无防堆积特性会产生大量 “无效排队任务”,这些任务在主线程空闲后会连续执行,占用本可以给 setTimeout 或其他任务的时间;
  • 两者的任务都是耗时 2 秒的长任务,叠加后主线程被长时间占用,导致后续任务(包括定时器回调)的等待时间被无限拉长,实际执行时间与预期时间的偏差越来越大,最终总耗时远超过理论值。

总结:setInterval vs setTimeout 精度对比

特性setInterval(无防堆积)setTimeout 递归调用
间隔计算起点上一次触发时刻(不考虑执行耗时)上一次执行完成时刻(考虑执行耗时)
任务堆积风险高(间隔 < 执行耗时会导致任务排队)低(每次完成后才安排下一次,无堆积)
时间精度差(受执行耗时和堆积影响,偏差随时间增大)较好(间隔相对稳定,但仍受其他任务阻塞影响)
与其他定时器共存时易相互阻塞,精度进一步下降,总耗时增加相对独立,但仍可能被其他任务(如 setInterval 堆积任务)阻塞

结论:在存在长任务(如 2 秒执行时间)的场景中,setInterval 的无防堆积特性会导致任务堆积和时间精度严重下降;而 setTimeout 递归调用的精度相对更可控,但两者同时运行时,单线程的阻塞会让彼此的精度都大幅降低,最终导致实际执行时间远超过预期,造成 “时间浪费”。

如果需要更高的时间精度,通常建议:

  1. 避免使用 setInterval 执行长任务,改用 setTimeout 递归调用;
  2. 尽量缩短单次任务的执行时间(比如拆分长任务为微任务);
  3. 必要时使用 Web Worker 分担计算压力,避免主线程阻塞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95325.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95325.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/95325.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek-R1-0528 推理模型完整指南:领先开源推理模型的运行平台与选择建议

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【AI实战】从零开始微调Qwen2-VL模型:打造制造业智能安全巡检系统

【AI实战】从零开始微调Qwen2-VL模型&#xff1a;打造制造业智能安全巡检系统&#x1f3af; 项目背景与目标&#x1f6e0; 环境准备硬件要求软件环境搭建&#x1f4ca; 数据准备&#xff1a;构建高质量训练集第一步&#xff1a;提取规章制度知识第二步&#xff1a;创建标注数据…

5 重复匹配

在前几章里&#xff0c;我们学习了如何使用各种元字符和特殊的字符集合去匹配单个字符。本章将学习如何匹配多个连续重复出现的字符或字符集合。5.1 有多少个匹配你现在已经学会了正则表达式的模式匹配中的基础知识&#xff0c;但目前所有的例子都有一个非常严重的局限。请大家…

【浏览器兼容性处理】

浏览器兼容性处理是前端开发中重要的一环&#xff0c;指解决不同浏览器&#xff08;或同一浏览器不同版本&#xff09;对HTML、CSS、JavaScript解析执行存在差异&#xff0c;导致页面显示异常或功能失效的问题。以下是常见问题及系统的处理方案&#xff1a; 一、常见兼容性问题…

Android组件化实现方案深度分析

组件化是解决大型应用代码臃肿、耦合严重、编译缓慢、团队协作困难等问题的关键架构手段&#xff0c;其核心在于 模块化拆分、解耦、独立开发和按需集成。 一、 组件化的核心目标与价值 解耦与高内聚&#xff1a; 将庞大单体应用拆分为功能独立、职责单一的模块&#xff08;组件…

外卖:重构餐饮的线上服务密码

外卖不是 “把堂食菜装进盒子送出去”&#xff0c;而是 “用线上化服务重构餐饮与用户连接” 的经营模式 —— 它的核心&#xff0c;是 “让用户在家也能吃到‘像在店里一样好’的体验”。一、外卖的底层逻辑用户点外卖&#xff0c;本质是 “想在家获得‘餐厅级体验’”&#x…

C++——高性能组件

文章目录一、什么是高性能组件1.1 C 中高性能组件的核心设计原则1.2 常见的 C 高性能组件 / 库举例1.3 实现高性能组件的关键工具二、定时器2.1 什么是用户态定时器2.2 为什么要使用用户态定时器2.3 高性能用户态定时器的实现原理2.3.1 训练营2.3.1.1 问题解析2.3.1.2 模拟问答…

【软考中级网络工程师】知识点之 UDP 协议:网络通信中的高效轻骑兵

目录一、UDP 协议简介二、UDP 协议特点2.1 无连接性2.2 不可靠性2.3 面向数据报2.4 低开销2.5 广播支持三、UDP 协议工作原理3.1 UDP 报文格式3.2 UDP 数据传输过程四、UDP 协议应用场景4.1 实时音视频传输4.2 在线游戏4.3 DNS 查询4.4 其他应用场景五、UDP 与 TCP 对比5.1 可靠…

【Node.js从 0 到 1:入门实战与项目驱动】2.1 安装 Node.js 与 npm(Windows/macOS/Linux 系统的安装步骤)

文章目录 第 2 章:环境搭建 —— 准备你的开发工具 2.1 安装 Node.js 与 npm(Windows/macOS/Linux 系统的安装步骤) 一、通用安装前检查 二、Windows 系统安装步骤 方法 1:通过官方安装包(推荐) 方法 2:通过 nvm-windows 管理多版本(进阶) 三、macOS 系统安装步骤 方法…

C语言相关简单数据结构:数据结构概念

目录 1.需要的储备知识 2.数据结构相关概念 2.1 什么是数据结构 什么是数据&#xff1f; 什么是结构&#xff1f; 概念&#xff1a; 总结&#xff1a; 2.2 为什么需要数据结构&#xff1f; 结论&#xff1a; C语⾔语法基础到数据结构与算法&#xff0c;前⾯已经掌握并…

Docker 详细介绍及使用方法

Docker 详细介绍及使用方法 一、Docker 是什么&#xff1f; Docker 是一种开源的应用容器引擎&#xff0c;基于 Go 语言开发并遵从 Apache 2.0 协议开源。它允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上。Dock…

PHP request文件封装

1.继承FormRequest 其中id是路由传参 name是对象中必填校验<?phpnamespace App\Http\Requests\Admin\User;use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Rule;class user_info_uptRequest extends FormRequest {public function authorize():…

基于跨平台的svg组件编写一个svg编辑器

duxapp 提供了一套跨平台的 SVG 编辑器组件&#xff0c;支持在多种环境中创建和编辑 SVG 图形。该编辑器包含以下核心功能&#xff1a; 插入图片绘制自由路径添加文本创建基本形状&#xff08;矩形、圆形、线条等&#xff09;对元素进行移动、缩放和旋转操作 快速开始 import…

react+echarts实现图表展示的两种方法

前言&#xff1a;reactecharts实现图表展示。1、直接用echarts的插件来实现1&#xff09;安装npm install echarts2&#xff09;使用1、useEffect是react中集合onload/watch监听等方法与一体的hook函数&#xff0c;他的第二个参数是空数组&#xff0c;则等同于onload&#xff0…

Apache 服务器基础配置与虚拟主机部署

Apache 服务器基础配置与虚拟主机部署 Apache 的核心定位与作用&#xff1a; Apache 的核心功能是处理 HTTP 请求并提供 Web 资源&#xff0c;是客户端&#xff08;如浏览器&#xff09;与 Web 服务器之间的 “中间人”&#xff1a; 接收客户端通过 HTTP/HTTPS 协议发送的请求…

线性代数 · 矩阵 | 最小多项式

注&#xff1a;本文为 “矩阵 | 最小多项式” 相关合辑。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 最小多项式 橘子蜂蜜 于 2019-05-22 22:48:25 发布 根据哈密顿 - 凯莱&#xff08;Hamilton - Cayley&#xff09;定理&#xff0c;任给数域 PPP 上的一个 …

docter的使用、vscode(cursor)和docker的连接,详细分析说明

目录 一、基本命令 二、用案例来学习使用方法 &#x1f680; Pull Python 3.11 镜像并创建命名容器 &#x1f4cb; 其他有用命令 在容器中安装依赖 三、直接在镜像中安装依赖&#xff08;创建自己定制的镜像&#xff09; 四、在 cursor 中选用容器作为编译器 五、对于整…

如何使用AI大语言模型解决生活中的实际小事情?

我们总以为AI是遥不可及的未来科技&#xff0c;却忽视了它早已成为生活中最实用的“隐形助手”。在信息爆炸的今天&#xff0c;我们每天被无数生活琐事包围&#xff1a;一封专业邮件反复修改措辞、孩子突如其来的数学难题、冰箱里仅剩的食材如何搭配、旅行行程的繁琐规划……这…

关于微信小程序的笔记

1.需要获取demo素材图片方法&#xff08;2,3&#xff09;2.使用逆向工具进行解包没有安装node的需要安装一下安装npm i -g wedecode0.8.0-beta.3获取小程序文件存放路径/Users/lin/Library/Containers/com.tencent.xinWeChat/Data/.wxapplet/packages/wx060ecb4f74eac0da根据具…

课堂笔记:吴恩达的AI课(AI FOR EVERYONE)-W2 AI项目工作流程

课堂笔记&#xff1a;吴恩达的AI课&#xff08;AI FOR EVERYONE&#xff09;-W2 AI项目工作流程 一、如何开始一个AI项目&#xff1f; 1、建设项目工作流程 2、选择合适的AI项目 3、为这个项目收集数据和组织团队二、AI项目的工作流程 &#xff08;1&#xff09;机器学习项目的…