JS中setTimeout和setInterval的最大延时值详解


Posted in Javascript onFebruary 13, 2017

前言

JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()setInterval()这两个函数来完成。而这篇文中主要给大家介绍的是关于JS中setTimeout和setInterval最大延时值的相关问题,需要的朋友们下面来一起学习学习吧。

先来看这样一段代码:

function update() {
 loadData().then(function(data) {
  $('#content').html(data.content);
  var delay = data.nextUpdateTime - new Date();
  if (delay > 0) {
   setTimeout(update, delay);
  }
 });
}

其流程非常简单:通过AJAX加载数据后更新HTML的内容;如果有指定下次更新时间,则通过计时器在该时间点再执行一次整个流程。

要说这段代码有什么隐患的话,那就是data.nextUpdateTime与当前时间的时间差(即delay变量的值)比较小的时候,会导致内容频繁更新。但这是属于正常的业务逻辑,要优化就只能牺牲内容更新的即时性。然而这里我要说的是,当时间差非常大的时候,也会出现同样的问题。

下面模拟一下这个场景:

function log() {
 console.log('executed');
}

var nextUpdateTime = new Date();
// 设为一个月后
nextUpdateTime.setMonth(nextUpdateTime.getMonth() + 1);

var delay = nextUpdateTime - new Date();
setTimeout(log, delay);

这段代码的原意是让log函数在一个月后执行,但是运行一下就可以发现,该函数会马上执行。为什么会这样呢?

搜一下相关内容可以发现,setTimeout是使用Int32来存储延时参数值的,也就是说最大的延时值是2^31-1。一旦超过了最大值,其效果就跟延时值为0的情况一样,也就是马上执行。

这个最大的延时值已经接近一个月了,一般情况下,用户也不会长时间开着一个网页,如果真开了这么久,那就刷新一下吧:

function update() {
 loadData().then(function(data) {
  $('#content').html(data.content);
  var delay = data.nextUpdateTime - new Date();
  if (delay > 0) {
   // 限制最大延时值为一天
   var ONE_DAY = 24 * 60 * 60 * 1000;
   if (delay > ONE_DAY) {
    setTimeout(function() {
     window.location.reload();
    }, ONE_DAY);
   } else {
    setTimeout(update, delay);
   }
  }
 });
}

同样的问题也存在于setInterval中。这也算是Javascript中一个比较隐蔽的坑了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
Jan 15 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
Mar 01 Javascript
JavaScript电子时钟倒计时第二款
Jan 10 Javascript
Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
Jul 01 Javascript
自己封装的一个简单的倒计时功能实例
Nov 23 Javascript
利用vue写todolist单页应用
Dec 15 Javascript
jQuery基于ajax操作json数据简单示例
Jan 05 Javascript
ES6与CommonJS中的模块处理的区别
Jun 13 Javascript
Vue插槽原理与用法详解
Mar 05 Javascript
详解elementui之el-image-viewer(图片查看器)
Aug 30 Javascript
JS模拟实现京东快递单号查询
Nov 30 Javascript
关于Javascript闭包与应用的详解
Apr 22 Javascript
Vue.js实现简单动态数据处理
Feb 13 #Javascript
JavaScript获取select中text值的方法
Feb 13 #Javascript
详谈$.data()的用法和作用
Feb 13 #Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
Feb 13 #Javascript
JavaScript实现公历转农历功能示例
Feb 13 #Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
Feb 13 #Javascript
jQuery源码分析之sizzle选择器详解
Feb 13 #Javascript
You might like
PHP 获取文件路径(灵活应用__FILE__)
2013/02/15 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
dojo学习第二天 ajax异步请求之绑定列表
2011/08/29 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
2013/05/10 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
jquery 层次选择器siblings与nextAll的区别介绍
2013/08/02 Javascript
javascript怎么禁用浏览器后退按钮
2014/03/27 Javascript
jQuery淡入淡出元素让其效果更为生动
2014/09/01 Javascript
超炫的jquery仿flash导航栏特效
2014/11/11 Javascript
node.js使用require()函数加载模块
2014/11/26 Javascript
BootStrap实现树形目录组件代码详解
2016/06/21 Javascript
Vue2实现组件props双向绑定
2016/12/02 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
Vue.js父与子组件之间传参示例
2017/02/28 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
利用JQuery操作iframe父页面、子页面的元素和方法汇总
2017/09/10 jQuery
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
mongodb初始化并使用node.js实现mongodb操作封装方法
2019/04/02 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
js回调函数仿360开机
2019/12/26 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
[02:53]DOTA2亚洲邀请赛 NewBee战队巡礼
2015/02/03 DOTA
python回溯法实现数组全排列输出实例分析
2015/03/17 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
解决python中0x80072ee2错误的方法
2020/07/19 Python
Linux如何修改文件和文件夹的权限
2013/09/05 面试题
大学生职业生涯设计书
2014/01/02 职场文书
syb养殖创业计划书
2014/01/09 职场文书
就业意向书范文
2014/04/01 职场文书
2015年语文教研组工作总结
2015/05/23 职场文书
公司年会主持词范文!
2019/05/07 职场文书
七年级作文之雪景
2019/11/18 职场文书
Mysql分析设计表主键为何不用uuid
2022/03/31 MySQL
Python实战之大鱼吃小鱼游戏的实现
2022/04/01 Python
netty 实现tomcat的示例代码
2022/06/05 Servers
Python中np.random.randint()参数详解及用法实例
2022/09/23 Python