函数的防抖与节流

90 阅读2分钟

防抖: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

//函数防抖([]里的内容可选)
const debounce = (fn, delay) => { //fn是要执行的函数(delay为延迟时间)
    let timer = null;
    return ([...args]) => { //给fn传入对应的实参,用rest参数接收
        clearTimeout(timer);  //清空之前的定时器
        timer = setTimeout(() => {
            fn.apply(this[, args]);  //改变args数组的指向
            //fn.call(this[,...args])  //也可用call,但是第二个参数必须是参数列表
        }, delay);
    };
};
应用场景:a.按钮提交(防止多次提交按钮,只执行最后一次提交)
         b.搜索框的搜索功能(用防抖来节约请求资源)

节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有 一次生效。

//函数节流(法一)
const throttle = (fn, delay) => {  //throttle用来返回节流函数的工具函数
    let flag = true;
    return ([...args]) => {  //真正的节流函数
        if (!flag) return;
        flag = false;
        setTimeout(() => {
            fn.apply(this[, args]);
            flag = true;
        }, delay);
    };
};
 
//节流(法二,用时间戳实现节流)
//节流函数,只有大于设定的周期才会执行第二次
function throttle(fn, delay) {
    let lastTime = 0;  //第一次要立即调用(记录上一次触发时间)
    return function([event]) {
        let nowTime = Date.now();  //记录当前函数触发的时间
        if (nowTime - lastTime > delay) { //判断相隔的两次触发是否满足延时(时差>延时,才调用)
            fn.call(this[,evevt]); //改变this,this指向window
            lastTime = nowTime; //记录此次调用时间
        }
    }
}
应用场景:a.拖拽功能的实现(固定时间内只执行一次)
         b.动画场景(避免短时间内多次触发动画)
         c.调节浏览器窗口大小(不断的调整浏览器窗口大小会不断的触发resize事件,用
           防抖来让其只触发一次)