摘要:也就是说,代码队列中仅能有一个间歇定时器在等待。这导致两个问题,一是某些间隔会跳过,二是多个定时器的代码之间的间隔可能比预期的小。
定时器:间歇调用和超时调用
超时调用:setTimeout(),接受两个参数,第一个参数是可执行的JavaScript代码字符串,或是回调函数,第二个参数是毫秒为单位的插入代码队列的的时间。
清除方式:clearTimeout(),参数是设置setTimeout时返回的数值ID。
var timeId = setTimeout(function(){ alert("hello world"); }, 5000); clearTimeout(timeId);
间歇调用:setInterval(),接受的两个参数和setTimeout()类似,只是时间参数代表两次间隔插入代码队列的的时间。
清除方式:clearInterval(),参数是设置间歇调用时返回的数值ID。清除间歇调用很重要,因为不清除就会一直执行,也就是一直在JavaScript的时间线中。因为JavaScript是单线程执行的,也就是说如果不清除间歇调用,代码队列中的其他的代码即使进入了代码也是无法执行的。事实上,间歇调用导致的问题不止如此。
var timeId = setInterval(function(){ alert("hello world"); }, 5000); clearInterval(timeId);
一般没有必要跟踪超时调用的ID,因为执行一次之后就自动清除了;但是间歇调用最好人工清除,或者采用超时调用模拟间歇调用,这还有另外一个好处。
JavaScript的时间线及间歇调用的困扰JavaScript是单线程执行的,不同时期由不同的代码控制JavaScript时间线,由浏览器从代码队列中选择特定的代码执行。定时器中设置的时间实际上是指定时器代码进入代码队列的时间,实际开始运行时间取决于JavaScript进程是否空闲,如果不空闲就要等待正在执行的代码完成执行。
var btn = document.getElementById(“my-btn”); btn.onclick = function(){ setTimeout(function(){ document.getElementById(“message”).style.visibility = “visible”; }, 250); };
上图设置了一个250ms后的timer,但是由于onclick事件处理程序要执行300ms,即使到了255ms,timer也是不执行的,直到onclick执行完才能执行。
JavaScript的这种单线程执行方式导致了浏览器添加间歇定时器代码时,仅能等待队列中没有该定时器的代码实例时才能加进去,否则加不进去。也就是说,代码队列中仅能有一个间歇定时器在等待。这导致两个问题,一是某些间隔会跳过,二是多个定时器的代码之间的间隔可能比预期的小。
上图表明,205ms加入的定时器在300ms开始执行,由于定时器执行时间超过一个时间间隔(200ms),在405ms第二个定时器进入队列,但是605ms时的代码却难以进入队列了,这是因为405ms进入的代码还在队列中。
为了避免重复定时器的缺点,常使用超时定时器模拟间歇定时器,如下:
setTimeout(function(){ //processing setTimeout(arguments.callee, interval); }, interval); 具体的使用实例如下:定时器的使用:数组分块(array chunking)和函数节流(function throttling)the onlt one div
数组分块的原因:JavaScript的功能是被限制的,无法像桌面应用一样无限制的占有资源。其中一个限制就是执行时间的限制,如果代码执行超过特定的时间或者特定的语句数目就禁止继续执行。因此,在处理大规模数组时,可以使用定时器将数组分为多个块间断执行,JavaScript进程有时间在处理数组项目的事件之间转入空闲,这样整个数组项目项目的处理就不会受执行时间限制。实现数组分组的函数如下:
the onlt one div
函数节流的原因:浏览器中某些计算很耗费资源,包括CPU和内存,例如resize操作,因此如果循环执行这些操作会使浏览器崩溃。函数节流的原理类似于数组分块,也就是某一个执行代码用定时器分位数块执行。不详细介绍。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/80610.html
摘要:也就是说,代码队列中仅能有一个间歇定时器在等待。这导致两个问题,一是某些间隔会跳过,二是多个定时器的代码之间的间隔可能比预期的小。 定时器:间歇调用和超时调用 超时调用:setTimeout(),接受两个参数,第一个参数是可执行的JavaScript代码字符串,或是回调函数,第二个参数是毫秒为单位的插入代码队列的的时间。清除方式:clearTimeout(),参数是设置setTimeo...
摘要:如果构造函数窃取结合使用原型链或者寄生组合则可以解决这个问题惰性载入函数惰性载入表示函数执行的分支仅会发生一次。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。,用于注销某个事件类型的事件处理程序。 高级技巧 高级函数 安全的类型检测 typeof操作符在检测数据类型时,可能会得到不靠谱的结果 instanceof操作符在存在多个全局作用域,也就是页面包含多个iframe的...
摘要:解决方式是,当我们不使用它们的时候,手动切断链接淘汰把和对象转为了真正的对象,避免了使用这种垃圾收集策略,消除了以下常见的内存泄漏的主要原因。以上参考资料高程垃圾收集类内存泄漏及如何避免内存泄露及解决方案详解类内存泄漏及如何避免 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1ft1ikzcqzqj30ka0et77a.jpg); 前言 起...
摘要:图二解读定时器可以在指定时间把定时器代码加入待执行队列,但并不能保证代码执行时机,待执行队列中的代码要等进程空闲时才能执行。也就是说定时器每隔间隔触发一次,尝试加入队列,拥堵时段将直接忽略本次操作。 图片出自JS高程(第三版) showImg(https://segmentfault.com/img/bVbgC3V?w=1337&h=313); 图一解读:JS运行于单线程的环境中:页面...
摘要:封装方法也比较简单,书中对此问题也进行了处理使用定时器,让函数延迟秒后执行,在此秒内,然后函数再次被调用,则删除上次的定时器,取消上次调用的队列任务,重新设置定时器。 在实际开发中,函数一定是最实用最频繁的一部分,无论是以函数为核心的函数式编程,还是更多人选择的面向对象式的编程,都会有函数的身影,所以对函数进行深入的研究是非常有必要的。 函数节流 比较直白的说,函数节流就是强制规定一...
阅读 1951·2021-09-07 10:24
阅读 2086·2019-08-30 15:55
阅读 2037·2019-08-30 15:43
阅读 668·2019-08-29 15:25
阅读 1043·2019-08-29 12:19
阅读 1927·2019-08-23 18:32
阅读 1515·2019-08-23 17:59
阅读 946·2019-08-23 12:22