节流、防抖

182 阅读1分钟

节流throttle

一定间隔后执行一次。

简单

  • (首节流)闭包+时间戳闭包保存上次时间戳,与触发时的时间戳对比。
function throttle(fn, delay) => {
  let previous = 0;
  return function(...args) {
    let now = Date.now();
    if (now - previous > delay) {
      fn.apply(this, args);
      previous = now;
    }
  }
}
  • (尾节流)闭包+定时器:间隔内=存在定时器,定时器顺利结束后执行+重置。
function throttle(fn, delay) => {
  let timer = null;
  return function(...args) {
    if(!timer) {
      timer = setTimeout(()=>{
        clearTimeout(timer);
        fn.apply(this, args);
      }, delay);
    }
  }
}

lodash

  • 有头有尾
  • 有头
  • 有尾

防抖debounce

频发触发事件,只执行一次。中途触发则取消执行。

简单

闭包+定时器:触发事件,启动一个定时器;再次触发,重置定时器,直到定时器顺利结束。

function debounce(fn, delay) => {
  let timer = null;
  return function(...args) {
    if(timer) clearTimeout(timer); 
    timer = setTimeout(()=>{
      fn.apply(this, args);
    }, delay);
  }
}
  • n秒后执行最后一次

  • 执行第一次,n秒后再执行

lodash

注意

闭包

  • 保存变量。Eg.上次的定时器id、时间戳
  • 返回带定时器的新函数,触发事件时执行。

为什么要绑定this?

避免this丢失。this应指向我们想要的对象。

箭头函数写法,this指向外部词法作用域