JS手写防抖函数和节流函数

157 阅读2分钟

JS手写防抖函数debounce和节流函数throttle

防抖(debounce)的概念?

触发高频事件后n秒内函数只会执行一次,如果n秒内再次触发,则重新计时。

防抖的使用场景

  1. 输入框输入搜索内容。
  2. 调整浏览器窗口大小。

防抖的理解

游戏中回城,多次触发回城技能,回城时间归零。

话不多说,接下来让我们手写一个防抖函数吧!

// 手写封装防抖函数
// 参数:1.操作函数 2.延迟时间 3.是否立即执行
function myDebounce(func, wait, isImmediate){
    let timer = null;
    return function(){
        console.log(arguments);
        // 让执行函数的this指向赋值给self
        let self = this;
        // 通过函数的隐式参数类数组arguments指向event
        let args = arguments;
        clearTimeout(timer);
        if(isImmediate){  // 立即执行
             func.apply(self, args);   // 改变执行函数的this指向
             timer = setTimeout(()=>{
                // 将第一次需要等待delay的n秒清零,即可以立即执行
                timer = null;
             })
        }else{
            // 不会立即执行
            timer = setTimeout(()=>{
                // 改变执行函数的this指向
                func.apply(self, args)
            },wait)
        }
    }
}

节流(throttle)的概念?

高频事件触发,但是在n秒内只能执行一次,n秒内再次触发无响应,节流会稀释掉函数的执行频率。

节流的使用场景

  1. 提交按钮,触发之后无法再次触发等待提交成功的响应。
  2. 浏览器滚动事件。

节流的理解

游戏中的攻击技能触发,只能等技能释放完毕才可以再次触发攻击。

手写节流代码

// 手写节流函数throttle
function myThrottle(func, delay){
    let timer;
    return function(){
        // 让执行函数的this指向赋值给self
        let self = this;
        // 通过函数的隐式参数类数组arguments指向event
        let args = arguments;
        if(timer){ // 判断是否在冷却时间内,在的话直接返回
            return;
        } else {
            // 不在冷却时间内,可以再次触发执行
            timer = setTimeout(()=>{
                func.apply(self, args);
                timer = null;
            }, delay)
        }
    }
}