当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 深入浅出理解JavaScript高级定时器原理与用法

深入浅出理解JavaScript高级定时器原理与用法

2018年08月08日  | 移动技术网IT编程  | 我要评论

本文实例讲述了javascript高级定时器原理与用法。分享给大家供大家参考,具体如下:

settimeout()setinterval()可以用来创建定时器,其基本的用法这里就不再做介绍了。这里主要介绍一下javascript的代码队列。在javascript中没有任何代码是立即执行的,一旦进程空闲则尽快执行。所以说定时器中设置的时间并不代表执行时间就一定相符,而是代表代码会在指定时间间隔后加入到队列中进行等待。如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行,表面上看上去好像代码就在精确指定的时间点上执行了。所以就会产生一些问题。

重复定时器

通常,我们使用setinterval方法来以相同时间间隔重复执行某段代码。但是使用该方法会有两个问题:第一个就是某些间隔会被跳过;第二个就是多个定时器的代码执行之间的间隔可能会比预期的小。

在这里,我们来举个例子:如果某个onclick事件处理程序使用setinterval设置了一个200ms间隔的重复定时器,如果事件处理程序花了300ms的时间完成,就会跳过一个时间间隔同时运行着一个定时器代码。

我们也可以通过下面的代码来得到结论:

//重复定时器
var i =0;
setinterval(function(){
 //如果事件处理时间长于间隔时间
 i++;
 for(var j=0;j<100000000;j++){}
 document.write(i+' ');
},100);
//可以明显感觉到时间间隔不相等

为了避免这种时间间隔的问题,我们可以采用链式调用settimeout方法来取代setinterval

//可以采用链式调用settimeout来取代setinterval
var i = 0;
settimeout(function(){
 //处理内容
 i++;
 for(var j=0;j<100000000;j++){}
 document.write(i+' ');
 //
 settimeout(arguments.callee,100);
},100);
//这样处理效果明显好多了。

每次函数执行的时候都会创建一个新的定时器,第二个settimeout调用使用了arguments.callee来获取对当前执行的函数的引用,并为其设置另外一个定时器。这样做是为了在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔,也保证了在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行。可谓一举两得,现在主流框架中的动画一般都是这样来实现重复定时的。

函数节流

定时器不仅仅是用来定时的,也可以用来缓解浏览器的压力。浏览器中某些计算和处理要比其他的昂贵很多,比如说dom操作,就会需要更多的内存和cpu时间,连续使用过多的dom操作可能会导致浏览器挂起,甚至崩溃。

函数节流的基本思想就是,某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置一个。目的就是为了在执行函数的请求停止一段时间后再执行。

代码如下:

//再来谈谈函数节流
function throttle(method,context){
 cleartimeout(method.tid);
 method.tid = settimeout(function(){
 method.call(context);
 },100);
}
//该函数接受两个参数,第一个是要执行的函数,第二个是作用域。
//使用方法demo
//未使用情况:
window.onresize = function(){
 var div = document.getelementbytagname(body);
 div.style.height = div.offsetwidth +'px';
}
//使用情况;
function resizediv(){
 var div = document.getelementbytagname(body);
 div.style.height = div.offsetwidth +'px';
}
window.onresize = function(){
 throttle(resizediv);
};
//只要代码是周期性执行的,都应该使用节流。

这样给用户的感觉并不会很大,确是给浏览器减少了不少的压力。函数节流也是很多框架常用的技巧之一。

demo示例:

//重复定时器
/*var i =0;
setinterval(function(){
 //如果事件处理时间长于间隔时间
 i++;
 for(var j=0;j<100000000;j++){}
 document.write(i+' ');
},100);*/
//可以明显感觉到时间间隔不相等
//可以采用链式调用settimeout来取代setinterval
/*var i = 0;
settimeout(function(){
 //处理内容
 i++;
 for(var j=0;j<100000000;j++){}
 document.write(i+' ');
 //
 settimeout(arguments.callee,100);
},100);*/
//这样处理效果明显好多了。
//以上就是重复定时器
//再来谈谈函数节流
function throttle(method,context){
 cleartimeout(method.tid);
 method.tid = settimeout(function(){
 method.call(context);
 },100);
}
//该函数接受两个参数,第一个是要执行的函数,第二个是作用域。
//使用方法demo
//未使用情况:
window.onresize = function(){
 var div = document.getelementbytagname(body);
 div.style.height = div.offsetwidth +'px';
}
//使用情况;
function resizediv(){
 var div = document.getelementbytagname(body);
 div.style.height = div.offsetwidth +'px';
}
window.onresize = function(){
 throttle(resizediv);
};
//只要代码是周期性执行的,都应该使用节流。

更多关于javascript相关内容感兴趣的读者可查看本站专题:《javascript时间与日期操作技巧总结》、《javascript查找算法技巧总结》、《javascript错误与调试技巧总结》、《javascript数据结构与算法技巧总结》、《javascript遍历算法与技巧总结》及《javascript数学运算用法总结

希望本文所述对大家javascript程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网