当前位置: 首页 > news >正文

setTimeout和setInterval的区别

setTimeout和setInterval这两个函数, 大家肯定都不陌生, 但可能并不是每个人都了解其内部的实质。

甚至可能会错误的把两个实现定时调用的函数理解成了类似thread一样的东西, 认为会在一个时间片内, 并发的执行调用的函数, 似乎很好很强大。但其实并不是如此, 实际的情况是javascript都是以单线程的方式运行于浏览器的javascript引擎中的。

setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入js引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要. 而且setTimeout和setInterval还有点不一样。

 

一、setTimeout

function click() {
  // code block1...
  setTimeout(function() {
    // process ...
  }, 200);
  // code block2
} 

假设我们给一个button的onclick事件绑定了此方法。

当我们按下按钮后, 肯定先执行block1的内容, 然后运行到setTimeout的地方, setTimeout会告诉浏览器说: "200ms后我会插一段要执行的代码给你的队列中", 浏览器当然答应了(注意插入代码并不意味着立马执行), setTimeout代码运行后, 紧跟其后的block2代码开始执行。

这里就开始说明问题了, 如果block2的代码执行时间超过200ms, 那结果会是如何? 或许按照你之前的理解, 会理所当然的认为200ms一到, 你的process代码会立马执行...事实是, 在block2执行过程中(执行了200ms后)process代码被插入代码队列, 但一直要等click方法执行结束, 才会执行process代码段, 从代码队列上看process代码是在click后面的, 再加上js以单线程方式执行, 所以应该不难理解. 如果是另一种情况, block2代码执行的时间<200ms, setTimeout在200ms后将process代码插入到代码队列, 而那时执行线程可能已经处于空闲状态了(idle), 那结果就是200ms后, process代码插入队列就立马执行了, 就让你感觉200ms后, 就执行了。

 

二、setInterval

这里可能会存在两个问题:
1.时间间隔或许会跳过
2.时间间隔可能小于定时调用的代码的执行时间

function click() {
  
// code block1...   setInterval(function() {     // process ...   }, 200);   // code block2 }

和上面一样我们假设通过一个click, 触发了setInterval以实现每隔一个时间段执行process代码

比如:onclick要300ms执行完, block1代码执行完, 在5ms时执行setInterval, 以此为一个时间点, 在205ms时插入process代码, click代码顺利结束, process代码开始执行(相当于图中的timer code), 然而process代码也执行了一个比较长的时间, 超过了接下来一个插入时间点405ms, 这样代码队列后又插入了一份process代码, process继续执行着, 而且超过了605ms这个插入时间点。

下面问题来了, 可能你还会认为代码队列后面又会继续插入一份process代码...... 真实的情况是,由于代码队列中已经有了一份未执行的process代码, 所以605ms这个插入时间点将会被"无情"的跳过, 因为js引擎只允许有一份未执行的process代码, 说到这里不知道您是不是会豁然开朗呢...

为了解决这种问题你可以用一种更好的代码形式:

setTimeout(function(){
  //processing
  setTimeout(arguments.callee, interval);
}, interval); 

这个估计稍微想一下, 就明白其中的好处了, 这样就不会产生时间点被跳过的问题了。

 

转载于:https://www.cnblogs.com/lvmylife/p/5603278.html

相关文章:

  • shell脚本编程
  • 数组常用的处理方法 map,forEach,filter, every,some, set, concat, find 等
  • 阿里云自定义监控配置实例
  • Import 和 link引入的区别
  • 菜鸟如何才能快速提高自己的编程技术
  • css使子元素在父元素居中的各种方法/ 子元素居中有哪些方案
  • display:inline-block的用法
  • IE盒模型和W3C盒模型有什么不同?
  • 400多万微信用户如何“变现”?凯叔说了五大秘诀与教训
  • 分别封装添加事件和移除事件的函数,用以解决兼容性问题
  • 缓存、加载、检查、状态
  • 写一个function,清除字符串前后的空格
  • ado 小测试
  • 经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用hack的技巧 ?
  • vmware网络的连接方式
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • 【技术性】Search知识
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • extract-text-webpack-plugin用法
  • mongodb--安装和初步使用教程
  • React16时代,该用什么姿势写 React ?
  • Shadow DOM 内部构造及如何构建独立组件
  • SQLServer插入数据
  • 工作中总结前端开发流程--vue项目
  • 关于使用markdown的方法(引自CSDN教程)
  • 面试总结JavaScript篇
  • 全栈开发——Linux
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 如何在GitHub上创建个人博客
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • Nginx实现动静分离
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • #1014 : Trie树
  • #Linux(权限管理)
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (六)激光线扫描-三维重建
  • (三)elasticsearch 源码之启动流程分析
  • (十三)Maven插件解析运行机制
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (五)MySQL的备份及恢复
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET 命令行参数包含应用程序路径吗?
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net反混淆脱壳工具de4dot的使用