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 相关文章推荐
用于节点操作的API,颠覆原生操作HTML DOM节点的API
Dec 11 Javascript
jQuery实现随意改变div任意属性的名称和值(部分原生js实现)
May 28 Javascript
让页面上两个div中的滚动条(滑块)同步运动示例
Aug 07 Javascript
js+jquery实现图片裁剪功能
Jan 02 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
May 20 Javascript
JavaScript数组迭代器实例分析
Jun 09 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
Jan 26 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
Jan 27 Javascript
多种js图片预加载实现方式分享
Feb 19 Javascript
XMLHttpRequest Level 2 使用指南
Aug 26 Javascript
微信小程序 框架详解及实例应用
Sep 26 Javascript
Vue项目从webpack3.x升级webpack4不完全指南
Apr 28 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
模仿OSO的论坛(四)
2006/10/09 PHP
windows xp下安装pear
2006/12/02 PHP
一些常用的php简单命令代码集锦
2007/09/24 PHP
php将数据库中的电话号码读取出来并生成图片
2008/08/31 PHP
php htmlspecialchars加强版
2010/02/16 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
2016/04/01 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
PHP ADODB生成HTML表格函数rs2html功能【附错误处理函数用法】
2018/05/29 PHP
javascript函数库-集合框架
2007/04/27 Javascript
javascript跑马灯悬停放大效果实现代码
2012/12/12 Javascript
用javascript添加控件自定义属性解析
2013/11/25 Javascript
重新认识vue之事件阻止冒泡的实现
2018/08/02 Javascript
vue项目设置scrollTop不起作用(总结)
2018/12/21 Javascript
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
[13:16]INFAMOUS vs VGJ T BO3
2018/06/07 DOTA
Python 分析Nginx访问日志并保存到MySQL数据库实例
2014/03/13 Python
Python使用urllib模块的urlopen超时问题解决方法
2014/11/08 Python
python实现12306火车票查询器
2017/04/20 Python
python交互界面的退出方法
2019/02/16 Python
python实现弹跳小球
2019/05/13 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
详解python第三方库的安装、PyInstaller库、random库
2021/03/03 Python
简单介绍CSS3中Media Query的使用
2015/07/07 HTML / CSS
美国复古街头服饰精品店:Need Supply Co.
2017/02/22 全球购物
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
电子商务毕业生求职信
2013/11/10 职场文书
银行职员自我鉴定
2014/04/20 职场文书
关工委先进个人事迹材料
2014/05/23 职场文书
2014教师党员个人自我评议
2014/09/20 职场文书
介绍信怎么写
2015/01/30 职场文书
学生个人总结范文
2015/02/15 职场文书
开学第一周总结
2015/07/16 职场文书
2019年英语版感谢信(8篇)
2019/09/29 职场文书