1. 1. 一、函数防抖:
  2. 2. 二、函数节流
  3. 3. 三、两者区别

防抖与节流(2019-4-24)

一、函数防抖:

  1. 什么是函数防抖:首先说明应用场景,就是在一个Input框中连续快速的输入时候如果绑定了onChange事件,那么输入的值一旦发生变化就会触发该函数,如果在这个回调函数中带有数据获取就会造成非常大性能损耗,因此需要有防抖,那么什么是防抖呢?防抖就是把多个快速触发的事件合并成一个事件,相当于只触发一次。如何合并也就是在用户不触发某事件一段之后再调用函数。
  2. 如何实现函数防抖:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
      function debounce(func, delay) {
    var timeout = 0;
    return function(e) {
    var args = arguments;
    console.log("清除",timeout,e.target.value)
    clearTimeout(timeout);
    console.log("新的",timeout, e.target.value)
    timeout = setTimeout(function(){
    console.log("----")
    func.apply(null, args); //这里接收的是一个参数数组,是外层函数的参数列表不是setTimeout
    },delay)
    };
    };

    var validate = debounce(function(e) {
    document.getElementById("div").innerHTML = e.target.value;
    console.log("change", e.target.value, new Date-0)
    },380);
    var val = function(e) {
    console.log(e.target.value);
    }

    // 绑定监听
    document.querySelector("input").addEventListener('input', validate);

    原理解析就是利用setTimeout设置输入回调的触发延迟时间,如果延迟时间还没有到,就清除上一次的timeoutId,清除之后这个异步操作就会从任务队列中删除,也就是永远不会触发这个回调了,对于没有清除的,就会执行,没有清除的意思就是说在这次函数调用之后没有快速的又进行一次调用,这样就实现了将多个快速的函数调用合并为一个,就是防抖。防抖可以应用在input的回调上,还有mousemovescroll以及resize

二、函数节流

  1. 什么是节流:对比水坝,就是让水流缓慢一些,但是不能不让水流流动,不让用户的事件触发,如果不触发就是防抖。也就是在用户频繁的触发事件中,间隔一段时间触发一次。
  2. 如何实现节流:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
       function throttle(fn, threshhold) {
    var timeout
    var start = new Date;
    var threshhold = threshhold || 160
    return function () {

    var context = this, args = arguments, curr = new Date() - 0

    clearTimeout(timeout)//总是干掉事件回调
    if(curr - start >= threshhold){
    console.log("now", curr, curr - start)//注意这里相减的结果,都差不多是160左右
    fn.apply(context, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
    start = curr
    }else{
    //让方法在脱离事件后也能执行一次
    timeout = setTimeout(function(){
    fn.apply(context, args)
    }, threshhold);
    }
    }
    }
    var mousemove = throttle(function(e) {
    console.log(e.pageX, e.pageY)
    });
    // 绑定监听
    document.querySelector("#panel").addEventListener('mousemove', mousemove);

三、两者区别

一个很直观的网站可以看到