节流与防抖

140 阅读2分钟
**节流与防抖:   防止函数多次调用。**都是用于**避免用户在规定的事件内多次点击导致多次处理**数据(多次发送请求)。将多次请求合并的一个策略。

节流:  一个函数在执行一次后, 只有大于设定的执行周期才会执行第二次。

高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

实现1: 有个需要频繁触发得到函数, 在规定时间内,只让函数触发的第一次生效。后面不不生效。

/**
* 节流函数
* @param fn 要被节流的函数
* @param delay 规定的时间周期
*/

function throttle(fun, delay) {
    var lastTime = 0; // 记录上一次被触发的时间
    return function(){
        var nowTime = new Date(); //记录当前触发函数的时间
        if(nowTime -lastTime > delay){
            fun.apply(this); //修正this的指向
            lastTime = nowTime; //同步时间
         }
    }
}
**实现2:**每次触发事件时,如果当前有等待执行的延时函数,则直接return
//节流throttle代码:
function throttle(fn) {
    let canRun = true; // 通过闭包保存一个标记
    return function () {
         // 在函数开头判断标记是否为true,不为true则return
        if (!canRun) return;
         // 立即设置为false
        canRun = false;
        // 将外部传入的函数的执行放在setTimeout中
        setTimeout(() => { 
        // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
        // 当定时器没有执行的时候标记永远是false,在开头被return掉
            fn.apply(this, arguments);
            canRun = true;
        }, 500);
    };
}

防抖: 一个需要频繁触发的函数, 在规定时间内, 只让最后一次生效,前面的不生效。

将多次操作合并为最后一次操作进行。

原理:  维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

**缺点:**如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟。

实现:   每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法.

function debounce(fun, delay){
    let time = null; //设置上一次的定时器
    return function(){
        if(time){ //当存在定时器, 则清除上一次的定时器
            clearTimeout(timer);
        }
        timer = setTimeout(function(){//重新设置新的定时器
            fun.apply(this);
        }, delay)
    }

}

区别函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数