debounce 防抖

185 阅读1分钟

防抖:事件触发 n 秒之后再执行,解决频繁触发事件的问题。

一、基础版

function debounce(func, await) {
    let timer;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(func, await);
    }
}

二、this 指向

function debounce(func, await) {
    let timer;
    return function () {
        const ctx = this;
        clearTimeout(timer)
        timer = setTimeout(function(){
          func.apply(ctx);
        }, await);
    }
}

三、参数

function debounce(func, await) {
    let timer;
    return function () {
        const ctx = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function(){
          func.apply(ctx,args);
        }, await);
    }
}

四、返回值和立即执行

function debounce(func, await = 300, immediate = true) {
    let timer;
    return function () {
        const ctx = this;
        const args = arguments;
        if(timer) clearTimeout(timer);
      	if(immediate){
          let callNow = !timer;
          timer = setTimeout(()=>{
            timer = null;
          }, await)
          if(callNow) return func.apply(ctx,args);
				}else {
          timer = setTimeout(function(){
            func.apply(ctx,args);
          }, await);
        }
    }
}

五、取消

function debounce(func, await = 300, immediate = true) {
    let timer;
    const debounced = function(){
        const ctx = this;
        const args = arguments;
        if(timer) clearTimeout(timer);
        if(immediate){
          let callNow = !timer;
          timer = setTimeout(()=>{
            timer = null;
          }, await)
          if(callNow) return func.apply(ctx,args);
        }else {
          timer = setTimeout(function(){
            func.apply(ctx,args);
          }, await);
        }
    }
    debounced.cancel = function(){
      if(timer) clearTimeout(timer);
      timer = null;
    }
    return debounced;
}