函数的防抖与节流

一、防抖与节流的联系

        相同点:防抖(Debounce)和节流(Throttle)都是用来控制某个函数在一定时间内触发次数,两者都是为了减少触发频率,以便提高性能以及避免资源浪费

        不同点:节流是第一个说了算,后续都会被节流阀屏蔽掉,防抖是最后一个说了算,前面启用的都会被清除

二、节流函数

        1.定义:节流就是指连续触发事件但是在 n 秒中只执行一次函数,节流会稀释函数的执行频率

        2.分类:        

        (1)使用时间戳实现的节流函数会在第一次触发事件时立即执行,以后每过 delay 秒之后才执行一次,并且最后一次触发事件不会被执行

        节流函数输入一个函数并返回一个函数(高阶函数)

        节流使用闭包,保存上一次触发回调的时间 last,执行函数 func,时间阀值delay

        在要执行 func 时,当前时间与上一次触发时间进行比较,如果时间间隔大于interval(now - last >= interval),执行函数 func.apply(context, args)

// 时间戳方式
// 节流 事件连续触发在n秒内只触发一次
function throttle(func, interval) {
  // last为上一次触发回调的时间
  let last = 0;
  // 将throttle处理结果当作函数返回
  return function() {
    // 保留调用时的this上下文
    let context = this;
    // 保留调用时传入的参数
    let args = arguments;
    // 记录本次触发回调的时间
    let now = Date.now();
    // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
    if (now - last >= interval) {
      // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
      last = now
      func.apply(this, args);
    }
  }
}

        (2)定时器实现的节流函数在第一次触发时不会执行,而是在 interval秒之后才执行,当最后一次停止触发后,还会再执行一次函数

// 定时器方式
function throttle1(func, interval) {
  let sign = true;
  return function() {
    // 在函数开头判断标志是否为 true,不为 true 则中断函数
    if (!sign) return;
    //  sign 设置为 false,防止执行之前再被执行
    sign = false;
    setTimeout(() => {
      func.apply(this, arguments)
      // 执行完事件之后,重新将这个标志设置为 true
      sign = true;
    }, interval)
  }
}

        3.使用场景 

        节流一般用于鼠标的跟随动画实现,scrollresizetouchmovemousemove等极易持续性促发事件的相关动画问题,降低频率




三、防抖函数

        1.定义:防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间



        防抖函数也是一个高阶函数,也使用了闭包,与节流不同,此处闭包保存的是setTimeout 返回的 timer,用于在后续持续触发之前及时取消定时器

        2.使用场景

        防抖一般用于表单元素的校验,如手机号,邮箱,用户名等,部分搜索功能的模糊查询结果实现




你可能感兴趣的:(前端,javascript,开发语言)