js 防抖和节流的实现(闭包的高级应用)

140 阅读2分钟

函数防抖

防抖

1概念:短时间内同时触发同一个函数,只执行最后一次或者只执行第一册次的函数

2 使用实例:

 防抖函数可适用于点赞、输入框校验、取消点赞、创建订单等不可让用户同一时间内频繁进行操作的场景

3 代码实现

/*
1 .传入三个参数 1 要只执行的函数 2 等待时间 ,3 是否立即执行 immediate=true

*/
function debounce(func, wait, immediate = false) {
    let timer = null //这一定是第一次 需要用它判断是否是第一次执行
    return function anonymous(...params) {
    // 也可以用 arguments 来接受参数
        let now = immediate && !timer; // 
        // 每次进来之前吧设置的计时器清除
        clearTimeout(timer)
        timer = setTimeout(() => {
            timer = null // 回归到初始状态
            // 绑定this 此this,为触发事件的this此 ...params为对象
            // wait 这么久的事件中没有触发第二次执行
            // func.call(this, ...params)
            !immediate ? func.call(this, ...params) : null
        }, wait)
        // 如果当前时立即执行
        // 如果立即执行
        now ? func.call(this, ...params) : null
    }

}

怎么给防抖里的函数传参时

btn.onclick=debounce(handel, 1000 ,true).bind(btn,{a:1},"value2")

节流

概念:在一次频繁的操作中可触发多次,但是频率是自己控制的 实列:1触发滚动条的滚动事件,2 改变窗口大小的事件: 代码

function throttle(func, wait = 300) {
    let timer = null,
        pervious = 0; //记录上次操作事件
    return function anonymous(...params) {
        let now = new Date(), // 判断间隔事件
            remaining = wait - (now - pervious); //记录还差多久 才能达到 我们一次触发的频率
        if (remaining <= 0) {
            // 能执行的时候 要把等待的定时器清除掉
            window.clearTimeout(timer)
            //两次操作的间隔时间已经操过 wait
            pervious = now // 把当前时间作为上一次的
            func.call(this, ...params)
        } else  if(!timer){ // 没定时器才要设置的
            //还不符合触发的频率
            timer = setTimeout(() => {
                timer=null ;// 每次正常执行 timers为null
                // 记录时间
                pervious =new Date();
                func.call(this, ...params)

            }, remaining)
        }
    }
}
function handel() {
    
    console.log("aa")

}
// window.onscroll=function(){
//     console.log("bb")
// }
// window.onscroll = handel; // 每次给滚动过程中浏览器有最后反时间(5-6ms,13-17ms)只要反应过来就会触发一次

   window.onscroll = throttle(handel,500);  // 控制执行的函数

//  window.onscroll = function anonymous() { }//相当于没隔5 毫秒触发一次函数 但是频率是自己的控制的


传参方式和防抖一样