循环定时器--用setTimeout代替setInterval
来源:互联网 发布:arpu值算法 编辑:程序博客网 时间:2024/05/23 05:08
续前缘 …
循环定时器的写法, 很多人应该熟悉
/* *func 回调 *interval 间隔时间*/setInterval(func, interval)
大部分人(包括之前的我)都将循环定时器理解为: 每间隔一段时间就执行一次回调. 其实这种说法并不准确. 如果强行这么理解, 那就要加上两个条件: JS进程永远处于空闲状态; 回调函数执行时间小于间隔时间.
可以做个试验:
setInterval(function(){ var script = document.createElement("script") script.src = "http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js" script.onload = script.onreadystatechange = function () { if (!script.readyState || 'loaded' === script.readyState || 'complete' === script.readyState) { console.log(new Date().getTime()) } }; document.querySelector("body").appendChild(script) }, 1000)
结果如下所示:
这串数据前后相隔时间虽然在1000上下徘徊, 但都不精确.
区分两件事情: JS进程和JS队列时间线是并行处理的; 同一时间, 定时器在队列中的回调函数只能有一个.
先说下间隔小于1000的情况: 假设间隔时间为t1, 代码执行时间为t2, 且t2>2t1, 此时定时器代码会跳过间隔时间且连续运行定时器代码. 直观呈现就是abs(time1-time2)<1000
.
再说下间隔大于1000: 当t2<2t1 && t2>t1 这属于正常情况
综上, 循环定时器是有问题的:
1. 某些间隔会被跳过
2. 多个定时器的代码执行时间可能会比预期的小
为了避免这两个问题的出现, setInterval可以采用链式调用setTimeout代替.
function Interval(){ this._interval_flag = null //初始化: 定时器在队列中的顺序}Interval.prototype = { createIns: function(fun, interval){ //创建定时器 var that = this //防止this指向发生变化 var fouth = setTimeout(function(){ if(typeof(fun) == "function"){ fun() }else{ return console.error("Type of the argument \"fun\" is not \"function\"") } that._interval_flag = setTimeout(arguments.callee, interval) }, interval) //链式调用setTimeout console.log("fouth:"+fouth) } ,clearIns: function(){ //清除定时器 clearTimeout(this._interval_flag) }}var subInterval = new Interval() //实例化subInterval.createIns(function(){ var script = document.createElement("script") script.src = "http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js" script.onload = script.onreadystatechange = function () { if (!script.readyState || 'loaded' === script.readyState || 'complete' === script.readyState) { console.log(new Date().getTime()) } }; document.querySelector("body").appendChild(script)}, 1000)
如上所述, 链式调用setTimeout替代setInterval, 可以保证: 在前一个定时器代码执行完之前, 不会像队列中插入新的定时器代码, 从而确保不会有任何确实的间隔; 此外, 还可以保证在下一次定时器代码执行之前, 至少要等待指定时长的间隔, 避免定时器代码连续运行.
有人可能会想, 多个定时器之间, 它们的顺序是怎样的. 其实定时器给自己开辟了一块内存来存放索引(只存放定时器: 包括单次和循环), 索引值从1开始无上限递增(如果定时器足够的话), 至于顺序则是按照定时器生成的时间顺序.
- 循环定时器--用setTimeout代替setInterval
- 定时器setTimeout()、setInterval()详解
- setTimeout和setInterval定时器
- 定时器setInterval,setTimeout
- 定时器setTimeout()、setInterval()详解
- 定时器setTimeout()、setInterval()详解
- setInterval setTimeout(定时器)
- setTimeout与setInterval 定时器与异步循环数组
- js定时器SetInterval与setTimeout
- 【javascript】【定时器】【setTimeout, setInterval】【优化】
- 关于setTimeout与SetInterval定时器
- js定时器setInterval和setTimeout
- jquery的定时器setTimeout()与定时循环执行器setInterval()的区别
- JS 定时器(setInterval和setTimeout 函数)
- JS 定时器 (setInterval 和 setTimeout 函数)
- 给定时器settimeout、setInterval调用传递参数
- js定时器setInterval、setTimeout的使用
- setTimeout / setInterval 定时器的一点思考
- 【excel 函数】常用的Excel函数
- Java数组
- HDU 4109 Instrction Arrangement (拓扑or差分约束求关键路径)
- cenos7安装svn
- Python:练习题(列表推导式、词频统计、异常处理、正则表达式等)
- 循环定时器--用setTimeout代替setInterval
- BLE主机主动扫描和被动扫描
- Java中HashMap遍历的两种方式
- web 连接 elasticsearch 中的问题
- jquery获取元素坐标获取鼠标坐标
- 如何使用FTP登录装着Win10 Iot系统的树莓派
- Mastering Android NDK Build System
- Adb相关
- memcached--查找命令--decr&&incr