函数防抖和节流

62 阅读1分钟

debounce 防抖函数

概念:在事件触发后的 n 秒之后再触发真正的函数,如果n秒之内事件又被触发,则会重新计时。

一个函数在某个规定的时间段内被多次调用,强制该函数在这个时间段内只执行最后一次。

    <ul>
        <li>normal<input type="text" id='inp' onkeyup="myfn()"></li>
        <li>被调用:<span id='count'>0</span></li>
        <li>debounce<input type="text" id='inp2' onkeyup="myfn2()"></li>
        <li>被调用:<span id='count2'>0</span></li>
    </ul>
//未处理,每次键盘触发都会被调用
function myfn(){
    const ipttext = document.getElementById('inp')
    const count = document.getElementById('count')
    let int =0;
    ipttext.onkeyup = function(){
        count.innerText = ++int
    }
}
//使用防抖函数,在 delay 时间内仅触发一次
   function debounce(fn, delay) {
        var timer = null;

        return function () {
            if (timer) {
                clearTimeout(timer);
            }

            timer = setTimeout(fn, delay || 50);
        };
    }
    
   function myfn2(){
    const ipttext2 = document.getElementById('inp2')
    const count2 = document.getElementById('count2')
    let innt2= 0;

    ipttext2.onkeyup=debounce(function(){
        count2.innerText = ++innt2
    },500)
}

如果用户在间隔时间内一直触发函数,而防抖函数内部真正需要执行的函数将永远无法执行。所以就要函数节流来解决

throttle 节流函数

概念:在规定的时间内函数触发多次,只执行一次函数。如果要执行多次只会到下一个周期里
    <ul>
        <li>throttle<input type="text" id='inp3' onkeyup="myfn3()"></li>
        <li>被调用:<span id='count3'>0</span></li>
        <li>调用时间:<span id='time3'></span></li>
    </ul>
function throttle(func, dur = 500) {
  let flag = null;
  return (...a) => {
    if (flag) {
      return;
    }
    flag = setTimeout(() => {
      clearTimeout(flag);
      flag = null;
    }, dur);
    func.apply(null, [...a]);
  };
}

function myfn3(){
    const ipttext3 = document.getElementById('inp3')
    const count3 = document.getElementById('count3')
    const time3 = document.getElementById('time3')
    let innt3= 0;
    let time = new Date().getMinutes() + ':' + new Date().getSeconds()
    ipttext3.onkeyup=throttle(function(){
        console.log('date===',new Date().getMinutes() + ':' + new Date().getSeconds())
        time3.innerText = new Date().getMinutes() + ':' + new Date().getSeconds()
        count3.innerText = ++innt3
    },1000)
}