zoukankan      html  css  js  c++  java
  • js高级技巧之高级定时器

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

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

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

    1.重复的定时器:

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

    (1)某些间隔会被跳过

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

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

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

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

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

    2.Yielding Processes

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

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

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

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

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

    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.函数节流:

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

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

    		function printValue(item) {
    			var div = document.getElementById('myDiv');
    			div.innerHTML += item + "</br>";
    		};
    		chunk(data.concat(), printValue);
    
    		// 函数节流
    		function throttle(method, context) {
    			clearTimeout(method.tId);
    			method.tId = setTimeout(function(){
    				method.call(context);
    			}, 100)
    		};
    
    		function resizeDiv() {
    			var div = document.getElementById('myDiv');
    			div.style.height = div.offsetWidth + "px";
    		};
    
    		window.onresize = function() {
    			throttle(resizeDiv);
    		};
    

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

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

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

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

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

  • 相关阅读:
    IntelliJ IDEA + Maven + Tomcat 本地开发、部署、调试。
    IntelliJ IDEA 修改IDE字体、代码字体。
    IntelliJ IDEA 自动导入包的问题
    jersey中的 404 Not Found 错误。
    IntelliJ IDEA 创建maven项目一次后,然后删除,再次保存到此目录下,提供此目录已经被占用的问题。
    修饰符(字符篇)
    [讨论] 2015-8-13日 主题:关于指针和堆栈
    HDFS异构存储
    HDFS异构存储
    HDFS副本放置策略
  • 原文地址:https://www.cnblogs.com/xinxingyu/p/4854492.html
Copyright © 2011-2022 走看看