js的函数节流和throttle和debounce详解:
同样是实现了一个功能,可能有的效率高,有的效率低,这种现象在高耗能的执行过程中区分就比较明显。
本章节一个比较常用的提高性能的方式,通常叫做"函数节流",下面就通过代码实例对此做一下介绍。
一.函数节流是什么:
在实际编码中,mousemove和resize是使用非常频繁的事件类型(当然还有其他类似事件类型),这样的事件有一个共同的特点,就是在一个普通的操作中,就有可能会在极短的时间内多次执行事件处理函数,会极大的损耗性能,比如resize事件,每次执行通常都会对dom元素进行重新计算,这是非常损耗性能的,何况是频繁的执行,所以在不影响效果的情况下尽可能的减少事件处理函数的执行次数是非常重要的。
二.函数节流的方式:
1.throttle方式:
此单词英文就有"节流"的意思。
更通俗的说就是调节函数执行的频率,控制函数连续两次执行的时间间隔。
下面一个代码:

[JavaScript] 纯文本查看 复制代码运行代码
1
2
3
4
5
6
7
8
9
var timer=null;
$(window).on('resize',function(){
  if(timer){
    clearTimeout(timer)
  }
  timer=setTimeout(function(){
    console.log("蚂蚁部落");
  },400);
});

代码实现了函数节流效果,当调整浏览器窗口大小的时候,"蚂蚁部落"就不会被输出,当调整停止后的400毫秒后才会输出。
上面的方式的的确确实现了函数节流效果,但是感觉有点太狠了,通常我们需要的不是当调整的时候不会输出,而是输出的频率低一点,实现这样的功能,后面会分享一段代码。
2.debounce方式:
此方式和throttle类似,但是它的关注点是函数调用的时间间隔,throttle的关注点是函数执行的时间间隔。
debounce方式对于控制长按键盘暴力输入这种现象非常有效。
三.实例代码:
如果相对函数节流彻底理解掌握,最好完整的分析一段实现此功能的源码。

[JavaScript] 纯文本查看 复制代码运行代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var throttle = function (fn,delay, immediate, debounce) { 
  var curr = +new Date(),
  last_call = 0,
  last_exec = 0,
  timer = null,
  diff,
  context,
  args,
  exec = function () {
    last_exec = curr;
    fn.apply(context, args);
  };
  return function () {
    curr= +new Date();
    context = this,
    args = arguments,
    diff = curr - (debounce ? last_call : last_exec) - delay;
    clearTimeout(timer);
    if(debounce){
      if(!immediate){
        timer=setTimeout(exec, delay);
      }
      else if(diff >= 0){
        exec();
      }
    }
    else{
      if(diff >= 0){
        exec();
      }
      else if(!immediate){
        timer = setTimeout(exec, -diff);
      }
    }
    last_call = curr;
  }
};

代码虽然将函数对象引用赋值给名为throttle的变量,其实它实现throttle和debounce两种方式,只要调整一下参数即可,下面就对它的实现过程做一下注释。
代码注释:
1.var throttle = function (fn,delay, immediate, debounce) {},此函数能够返回一个可以作为事件处理函数,具有四个参数,fn是一个函数对象,被节流的就是它的执行,delay规定延迟执行的时间,单位是毫秒,immediate是一个布尔值,如果是true,那么相关函数就会立即执行,否则延迟执行,debounce是个布尔值,如果是true,那么就是采用debounce方式。
2.var curr = +new Date(),获取当前时间,是一个时间戳。
3.last_call = 0,声明一个变量并初始化为0,它用来存储上一次试图调用函数的时间。
4.last_exec = 0,声明一个变量并初始化为0,它用来存储上一次函数函数执行的时间。
5.timer = null,声明一个变量,并初始化null,它会存储定时器函数的标识。
6.diff,用来存储时间差。
7.context,用来存储一个上下文对象。
8.args,用来存储函数的参数。
9.exec = function () {
  last_exec = curr;
  fn.apply(context, args);
};声明一个函数,此函数可以获取函数执行的事件,并且执行通过参数传递过来的fn函数。
10.return function () {},返回一个函数,被返回的这个函数就是不断被调用的事件处理函数。
11.curr= +new Date(),获取当前时间对象的时间戳。
12.context = this,将context赋值为this。
13.args = arguments,将参数对象集合赋值给变量args。
14.diff = curr - (debounce ? last_call : last_exec) - delay,这一个很有技巧,可以获取当前时间与延迟时间和上一次被调用的时间或者执行时间的时间差。
15. clearTimeout(timer),停止定时器函数的执行。
16.if(debounce){    if(!immediate){
    timer=setTimeout(exec, delay);
  } 
  else if(diff >= 0){
    exec();
  }
}
如果采用debounce方式,并且采用延迟方式,那么函数会延迟指定的时间再去执行,如果没有采用延迟方式,并且时间差大于等于0(说明延迟时间已到),就执行函数。
17.else{
  if(diff >= 0){
    exec();
  } 
  else if(!immediate){
    timer = setTimeout(exec, -diff);
  }
}
如果采用的是throttle方式,那么就会判断diff 是否大于0,如果大于0就执行函数,第一次执行的时候肯定会大于0,也就是说throttle方式在第一次执行的时候不会有延迟效果。如果不大于零,且采用延迟模式的话,就会延迟执行。
也许看了上面的介绍,对两种方式感觉比较混乱,那么可以参阅函数节流throttle和debounce代码演示一章节,这样就可以比较直观的观察两者的作用和相互间的区别了。

[概念] js的函数节流和throttle和debounce详解的更多相关文章

  1. JS的函数节流(throttle)

    什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...

  2. (转)JavaScript-性能优化之函数节流(throttle)与函数去抖(debounce)

     JavaScript-性能优化之函数节流(throttle)与函数去抖(debounce)         函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过 ...

  3. 函数防抖(Debounce)、函数节流 (Throttle)

    一篇介绍文章:https://zhuanlan.zhihu.com/p/38313717 演示示例:http://demo.nimius.net/debounce_throttle/ 函数防抖(Deb ...

  4. js实现的新闻列表垂直滚动实现详解

    js实现的新闻列表垂直滚动实现详解:新闻列表垂直滚动效果在大量的网站都有应用,有点自然是不言而喻的,首先由于网页的空间有限,使用滚动代码可以使用最小的空间提供更多的信息量,还有让网页有了动态的效果,更 ...

  5. str_replace函数的使用规则和案例详解

    str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...

  6. main.js index.html与app.vue三者关系详解

    main.js index.html与app.vue三者关系详解 2019年01月23日 11:12:15 Pecodo 阅读数 186   main.js与index.html是nodejs的项目启 ...

  7. js 高程 函数节流 throttle() 分析与优化

    在 js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下: 先看 函数节流 的定义,书上原话(斜体表示): 产生原因/适用场景: 浏览 ...

  8. JS魔法堂:函数节流(throttle)与函数去抖(debounce)

    一.前言 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1. window对象的resize.scroll事件 2. 拖拽时的mousemov ...

  9. JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我 ...

随机推荐

  1. 高质量程序设计指南C/C++语言——C++/C程序设计入门(3)

  2. HDU 5025Saving Tang Monk BFS + 二进制枚举状态

    3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS, ...

  3. php启用gzip压缩

    GZIP(GNU-ZIP)是一种压缩技术.经过GZIP压缩后页面大小可以变为原来的30%甚至更小.这样用户浏览的时候就会感觉很爽很愉快! 要实现GZIP压缩页面需要浏览器和服务器共同支持,实际上就是服 ...

  4. java困惑(二)函数以及引用改变

    具体的Visio 文档在资源

  5. Eclipse ADT 插件安装慢的解决的方法

    參考贴:http://blog.csdn.net/ludonghai715/article/details/6973433 在天朝非常多事情就不可避免的蛋疼,download.eclipse.org ...

  6. E. Riding in a Lift(Codeforces Round #274)

    E. Riding in a Lift time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. arm:jlink调试和直接烧写运行的不同 [mdk s3c2440]

    1.对全局变量的初始化. 2.还没发现的事例. /*************************************************/ 先上连接文件sct LR_ROM1 0x3000 ...

  8. xml学习(1)xml的几种文件格式

    1.先简单介绍一下XML,xml 是基于文本的标记性行语言,类似于html,可以方便存储数据 2,XML文件的几种格式: 格式1:查看一个 XML 的 CD 目录 <?xml version=& ...

  9. SQL Server 基础 03 查询数据基础

    查询数据 简单的查询 create table stu_info ( sno int not null ,sname ) not null ,sex ) not null ,birth ) not n ...

  10. 一些Xcode 5的使用提示和技巧

    摘自:http://www.cocoachina.com/newbie/env/2014/0127/7766.html 感谢论坛成员郭亚鑫的热心翻译.   在iOS开发中,Xcode 是最使用最多的I ...