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 相关文章推荐
js仿百度有啊通栏展示效果实现代码
May 28 Javascript
HTML长文本截取含有HTML代码同样适用的两种方法
Jul 31 Javascript
javascript数组去重方法终极总结
Jun 05 Javascript
javascript封装简单实现方法
Aug 11 Javascript
分享两段简单的JS代码防止SQL注入
Apr 12 Javascript
jQuery事件的绑定、触发、及监听方法简单说明
May 10 Javascript
全面了解addEventListener和on的区别
Jul 14 Javascript
使用Math.max,Math.min获取数组中的最值实例
Apr 25 Javascript
jQuery选择器之属性过滤选择器详解
Sep 28 jQuery
vue实现底部菜单功能
Jul 24 Javascript
JS实现十分钟倒计时代码实例
Oct 18 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
Nov 02 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 批量添加多行文本框textarea一行一个
2014/06/03 PHP
PHP 常用的header头部定义汇总
2015/06/19 PHP
PHP生成制作验证码的简单实例
2016/06/12 PHP
thinkphp中多表查询中防止数据重复的sql语句(必看)
2016/09/22 PHP
PHP For循环字母A-Z当超过26个字母时输出AA,AB,AC
2020/02/16 PHP
css动画效果之animation的常用样式
2021/03/09 HTML / CSS
JavaScript 读取元素的CSS信息的代码
2010/02/07 Javascript
eval与window.eval的差别分析
2011/03/17 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
深入理解JQuery keyUp和keyDown的区别
2013/12/12 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
2014/09/24 Javascript
jQuery遍历对象、数组、集合实例
2014/11/08 Javascript
javascript实现表格增删改操作实例详解
2015/05/15 Javascript
基于jquery实现人物头像跟随鼠标转动
2015/08/23 Javascript
详解Document.Cookie
2015/12/25 Javascript
javascript中对象的定义、使用以及对象和原型链操作小结
2016/12/14 Javascript
Angular4如何自定义首屏的加载动画详解
2017/07/26 Javascript
在微信小程序中使用mqtt服务的方法
2019/12/13 Javascript
vue+axios 拦截器实现统一token的案例
2020/09/11 Javascript
微信小程序实现打卡签到页面
2020/09/21 Javascript
vuex刷新后数据丢失的解决方法
2020/10/18 Javascript
解决antd Form 表单校验方法无响应的问题
2020/10/27 Javascript
[02:21]十步杀一人,千里不留行——DOTA2全新英雄天涯墨客展示
2018/08/29 DOTA
非递归的输出1-N的全排列实例(推荐)
2017/04/11 Python
python xlsxwriter库生成图表的应用示例
2018/03/16 Python
python网络爬虫学习笔记(1)
2018/04/09 Python
Python装饰器原理与基本用法分析
2020/01/07 Python
Python转换itertools.chain对象为数组的方法
2020/02/07 Python
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
大学生求职中的自我评价
2013/10/01 职场文书
二手书店创业计划书
2014/01/16 职场文书
2014年学校安全工作总结
2014/11/13 职场文书
岳庙导游词
2015/02/04 职场文书
2015年国庆节活动总结
2015/03/23 职场文书
4S店销售内勤岗位职责
2015/04/13 职场文书
公司出差管理制度范本
2015/08/05 职场文书