防抖和节流的实现

95 阅读1分钟
防抖

简单版本的实现

function debounce(func, delay) {
  let timeout;
  return function() {
    let context = this;//保存this的指向
    let args = arguments; // 保存event对象
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, delay)
  }
}

防抖如果需要立即执行,可加入第三个参数用于判断,实现如下

function debounce(func, delay, immediate) {
  let timeout;
  return function() {
    let context = this;//保存this的指向
    let args = arguments; // 保存event对象
    if(timeout) clearTimeout(timeout); // timeout 不为null
    if(immediate){
        let callNow = !timeout; //第一次会立即执行,以后只有事件执行后才会再次触发;
        timeout = setTimeout(() => {
          timeout = null;
        }, delay)
        if(callNow) {
            func.apply(context, args);
        }
    } else {
        timeout = setTimeout(() => {
          func.apply(context, args);
        }, delay) 
    }
  }
}
节流

完成节流可以使用时间戳与定时器的写法;使用时间戳写法,事件会立即执行,停止触发后没有办法再次执行;

function throttled(fn,delay = 500) {
    let oldTime = Date.now();
    return function(...args) {
        let newTime = Date.time();
        if(newTime - oldTime >= delay){
            fn.apply(null, args);
            oldTime = Date.now();
        }
    }
}

使用定时器写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行

function throttled(fn,delay = 500) {
    let timer = null;
    return function(...args) {
        if(!timer){
            timer = setTimeOut(() => {
                fn.apply(this, args);
                timer = null;
            }, delay)
        }
    }
}