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 相关文章推荐
jQuery 插件 将this下的div轮番显示
Apr 09 Javascript
JQuery入门——用映射方式绑定不同事件应用示例
Feb 05 Javascript
js获得鼠标的坐标值的方法
Mar 13 Javascript
浅谈Javascript 数组与字典
Jan 29 Javascript
js实现支持手机滑动切换的轮播图片效果实例
Apr 29 Javascript
JavaScript动态改变div属性的实现方法
Jul 22 Javascript
快速解决jquery.touchSwipe左右滑动和垂直滚动条冲突
Apr 15 Javascript
微信小程序中做用户登录与登录态维护的实现详解
May 17 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
Aug 06 Javascript
扫微信小程序码实现网站登陆实现解析
Aug 20 Javascript
element ui分页多选,翻页记忆的实例
Sep 03 Javascript
vue倒计时刷新页面不会从头开始的解决方法
Mar 03 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
纯真IP数据库的应用 IP地址转化成十进制
2009/06/14 PHP
php简单分页类实现方法
2015/02/26 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
jquery为页面增加快捷键示例
2014/01/31 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
Bootstrap每天必学之按钮
2015/11/26 Javascript
jquery实现鼠标悬浮停止轮播特效
2020/08/20 Javascript
Sea.JS知识总结
2016/05/05 Javascript
vue学习笔记之指令v-text && v-html && v-bind详解
2017/05/12 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
2017/12/07 Javascript
webpack4 css打包压缩问题的解决
2018/05/18 Javascript
JavaScript实现仿Clock ISO时钟
2018/06/29 Javascript
Vue中使用的EventBus有生命周期
2018/07/12 Javascript
Vue中Quill富文本编辑器的使用教程
2018/09/21 Javascript
JS删除String里某个字符的方法
2021/01/06 Javascript
六个窍门助你提高Python运行效率
2015/06/09 Python
Python中list初始化方法示例
2016/09/18 Python
Python解析excel文件存入sqlite数据库的方法
2016/11/15 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
python pandas dataframe 按列或者按行合并的方法
2018/04/12 Python
利用Python将每日一句定时推送至微信的实现方法
2018/08/13 Python
python反编译学习之字节码详解
2019/05/19 Python
CSS3 border-radius圆角的实现方法及用法详解
2020/09/14 HTML / CSS
Andrew Marc官网:设计师外套的领先制造商
2019/10/30 全球购物
Tahari ASL官方网站:高级设计师女装
2021/03/15 全球购物
JAVA软件工程师测试题
2014/07/25 面试题
高中生自我评价个人范文
2013/11/09 职场文书
面试后感谢信
2014/02/01 职场文书
2014学雷锋活动总结
2014/03/09 职场文书
社团活动总结模板
2014/06/30 职场文书
售房协议书
2014/08/19 职场文书
单位租房协议范本
2014/12/03 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书