实际上,浏览器负责进行排序,指派某段代码在某个时间点运行的优先级。

可以吧js想象成在时间线上运行的。

JavaScript中没有任何代码是立刻执行的,但一旦进程空闲则尽快执行。

1.重复的定时器:

setInterval()的重复定时器存在两个缺点:

(1)某些间隔会被跳过

(2)多个定时器的代码执行之间的间隔可能比预期的小;

假设,某个onclick事件处理程序使用setInterval()设置了一个200ms间隔的重复定时器。如果事件处理程序花了300ms多一点的时间完成,同时定时器代码也花了差不多的时间,就会同时出现跳过间隔且连续运行定时器代码的情况。

为了避免这个缺点,可以使用链式setTimeout()调用。

  1. setTimeout(function() {
  2. setTimeout(arguments.callee, interval);
  3. },interval)

callee是arguments的一个属性,指的是对函数对象本身的引用。

2.Yielding Processes

运行在浏览器中的JavaScript都被分配了一个确定数量的资源。

脚本长时间运行的问题通常是由两个原因之一造成的:

(1)过长的、过深嵌套的函数调用。

(2)进行大量处理的循环。

  1. for (var i = 0,len=data.length; i < len; i++) {
  2. process(data[i]);
  3. };

process要花100ms,那么总的花费时间是由数组的长度决定的。JavaScript的执行是一个阻塞操作,脚本运行花费的时间越久,用户无法与页面交互的时间也越久。

解决这个问题有一种技术叫做:数组分块

小块小块地处理数组,通常每次一小块。

基本的思路是为要处理的项目创建一个小队列,然后使用计时器取出下一个要处理的项目进行处理,接着再设置另一个定时器。

  1. function chunk(array, process, context) {
  2. setTimeout(function(){
  3. var item = array.shift();
  4. process.call(context, item);
  5.  
  6. if (array.length>0) {
  7. setTimeout(arguments.callee, 100);
  8. };
  9. }, 100)
  10. };
  11.  
  12. var data = [12,12,1234,453,436,23,23,5,4123,45,346,3563,2234,345,342];
  13.  
  14. function printValue(item) {
  15. var div = document.getElementById('myDiv');
  16. div.innerHTML += item + "</br>";
  17. };
  18. chunk(data.concat(), printValue);

chunk方法接收三个参数:要处理的项目的数组,用于处理项目的函数,运行该函数的环境。这个函数用来处理数组。

调用chunk时,为了不改变数组原来的值,用到了一个concat方法:(返回一个新的数组,此方法里面可以添加参数。这些参数和调用的数组组成一个新的数组。)。由于printValue函数处在全局作用域内,因此无需给chunk()传递一个context对象。

3.函数节流:

函数节流的思想是:某些代码不可以在没有间断的情况下连续重复执行。

第一次调用函数,创建一个定时器,在指定的时间间隔后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。

  1. function printValue(item) {
  2. var div = document.getElementById('myDiv');
  3. div.innerHTML += item + "</br>";
  4. };
  5. chunk(data.concat(), printValue);
  6.  
  7. // 函数节流
  8. function throttle(method, context) {
  9. clearTimeout(method.tId);
  10. method.tId = setTimeout(function(){
  11. method.call(context);
  12. }, 100)
  13. };
  14.  
  15. function resizeDiv() {
  16. var div = document.getElementById('myDiv');
  17. div.style.height = div.offsetWidth + "px";
  18. };
  19.  
  20. window.onresize = function() {
  21. throttle(resizeDiv);
  22. };

throtttle函数用来进行函数节流:这个函数首先清除之前设置的定时器。然后定义定时器,在100ms后再执行method方法(method.call(context)是为了确保方法在适当的环境中执行)。如果这个throttle在100ms内执行了50次,那么method方法也只会执行一次。(这就是节流)

window.onresize方法会造成浏览器运行缓慢的两个原因:

(1)首先,要计算offsetWidth属性,如果该元素或者页面上其他元素有非常复杂的css样式,那么整个过程将会很复杂。

(2)其次,设置某个元素的高度需要对页面进行回流来令改动生效。如果页面有很多元素同时应用了相当数量的css的话,这个又需要很多的计算。

只要代码是周期性执行的,都应该使用节流,但是你不能控制请求的执行的效率。可以改动throttle函数的时间间隔。

js高级技巧之高级定时器的更多相关文章

  1. JS高级技巧(简洁版)

    高级函数 由于在JS中,所有的函数都是对象,所以使用函数指针十分简单,也是这些东西使JS函数有趣且强大 安全的类型检测 JS内置的类型检测机制并不是完全可靠的 typeof 操作符返回一个字符串,表示 ...

  2. JS高级技巧学习小结

    安全类型检測 var isArray = value instanceof Array; 以上代码要返回true,value必须是一个数组,并且还必须与Array构造函数在同一个全局作用域中(Arra ...

  3. 关于普通定时器与高级定时器的 PWM输出的初始化的区别

    不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_ ...

  4. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  5. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

  6. Stm32高级定时器(二)

    Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...

  7. Stm32高级定时器(一)

    Stm32高级定时器(一) 1 定时器的用途 2 高级定时器框图 3 时基单元 4 通道 1 定时器的用途 已知一个波形求另一个未知波形(信号长度和占空比) 已知波形的信号长度和占空比产生一个相应的波 ...

  8. 关于js中两种定时器的设置及清除(转载)

    1.JS中的定时器有两种: window.setTimeout([function],[interval]) 设置一个定时器,并且设定了一个等待的时间[interval],当到达时间后,执行对应的方法 ...

  9. stm32高级定时器的应用——spwm

    用过stm32定时器的朋友都知道,定时器的CCR寄存器,可以用来配置PWM的输出,但同样也可以用来配置spwm.废话不多说,直接上代码. 首先,你得考虑一下几个因素: 1.同步调制还是异步调制.  2 ...

随机推荐

  1. suse linux 10 下配置vpn服务器(pptp)

     一.安装所需的软件包:      pptpd-*.rpm      ppp-*.rpm      pptp-*.rpm     一般情况下系统已经将pptp和ppp包安装好了,所以只需安装pptpd ...

  2. Effective C++ -----条款11: 在operator=中处理“自我赋值”

    确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...

  3. HDU 4966 GGS-DDU(最小树形图)

    n个技能,每个技能有0-a[i]的等级,m个课程,每个课程需要前置技能c[i]至少达到lv1[i]等级,效果是技能d[i]达到lv2[i]等级,花费w[i]. 输出最小花费使得全技能满级(初始全技能0 ...

  4. Silverlight 动画详解

    Animation规则 基于时间:你设置动画的初始状态,最终状态,及持续时间,Silverlight会计算帧速率. 作用于属性(properties):一个Silverlight动画只能做一件事情,在 ...

  5. 关于java中Double类型的运算精度问题

    标题     在Java中实现浮点数的精确计算    AYellow(原作) 修改    关键字     Java 浮点数 精确计算   问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...

  6. php date函数 参数详细

    time()在PHP中是得到一个数字,这个数字表示从1970-01-01到现在共走了多少秒,很奇怪吧 不过这样方便计算, 要找出前一天的时间就是 time()-60*60*24; 要找出前一年的时间就 ...

  7. Java使用JDBC连接MySQL数据库

    1.引用 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写 ...

  8. Ubuntu下安装Python3.4

    转自:http://blog.sina.com.cn/s/blog_7cdaf8b60102vf2b.html 1. 通过命令行安装Python3.4,执行命令:sudo apt-get instal ...

  9. javascript 面向对象编程小记

    虽然平常用jquery用的很熟,但是基本都是面向过程的写法.一个事件一个function,很少有面向对象的写法.今天得写一个日期控件,不得不用上面向对象编程. 刚开始我的想法是: var datepi ...

  10. Delphi中的基础数据类型

    参考http://www.cnblogs.com/del/archive/2007/12/04/982167.html 在学习之初,在这么多的数据类型中,最好记住这五种标准数据类型(整型.实型.字符型 ...