面试官:什么是防抖和节流,应用场景?

110 阅读4分钟

定义

防抖:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

多次触发 只执行最后一次

节流:n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

规定时间内 只触发一次

实现

防抖函数

1、需要接收什么参数

  • 参数一:回调的函数
  • 参数二:延迟时间
// 1.需要接收两个参数
function mydebounce(fn, delay) {  
}

2、返回值是什么

  • 最终我们返回结果是要绑定对应的监听事件的, 所以返回值一定是一个新的函数
// 1.需要接收两个参数
function mydebounce(fn, delay) {
  const _debounce = () => {}
  // 2.返回一个新的函数
  return _debounce
}

3、函数内部实现

  • 我们可以在_debounce函数中开启个定时器, 定时器的延迟时间就使用delay
  • 并且每开启一个定时器, 我们都需要将上一次的定时器取消掉
function mydebounce(fn, delay) {
  // 1.创建一个变量, 用于记录上一次定时器
  let timer = null

  // 2.触发事件时执行的函数
  const _debounce = () => {
    // 2.1第一次timer为null, 所有我们需要判断timer有值时清除定时器
    if (timer) clearTimeout(timer)

    // 2.2延迟执行传入的fn回调
    timer = setTimeout(() => {
      fn()
      // 2.3函数执行完成后, 我们需要将timer重置
      timer = null
    }, delay)
  }
  // 返回一个新的函数
  return _debounce
}

节流函数

1、需要接收什么参数

  • 参数一: 要执行的回调函数
  • 参数二: 要执行的间隔时间
// 1.需要接收两个参数, 第一个参数要执行的回调, 第二个参数间隔时间
function mythrottle(fn, interval) {

}

2、返回值是什么

  • 最终我们返回结果是要绑定对应的监听事件的, 所以返回值一定是一个新的函数
// 1.需要传入两个参数, 第一个参数要执行的回调, 第二个参数间隔时间
function mythrottle(fn, interval) {
  const _throttle = function() {

  }

  // 2. 返回一个新的函数
  return _throttle
}

3、函数内部实现 思路: 实现节流函数, 我们使用定时器是不方便管理的, 实现节流函数我们采用另一个思路

我们获取一个当前时间nowTime, 我们使用new Date().gettime()方法获取, 在设定一个开始时间startTime, 等待时间waitTime

waitTime = interval - (nowTime - startTime), 当前的时间减去开始的时间得到结果, 再使用间隔时间减去这个结果, 就可以得到等待时间

得到等待时间我们在进行判断, 如果等待时间小于等于0, 那么就可以执行回调函数

开始时间startTime我们初始值为0就好, 当第一次执行时, nowTime获取的时间戳是一个非常大的值, 得到的结果waitTime是负值, 所以第一次执行节流函数, 一定会立即执行, 这也符合我们要封装的效果

function mythrottle(fn, interval) {
  // 1.定义变量记录开始时间
  let startTime = 0

  const _throttle = function() {
    // 2. 获取当前时间
    const nowTime = new Date().getTime()
    // 3.计算需要等待的时间
    const waitTime = interval - (nowTime - startTime)

    // 4.当等待的时间小于等于0时, 执行回调函数 
    if (waitTime <= 0) {
      fn()
      // 并让开始时间等于现在时间 
      startTime = nowTime
    }
  }
  return _throttle
}

区别

相同点:

  • 都可以通过使用 setTimeout 实现
  • 目的都是,降低回调执行频率。节省计算资源

不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和 setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次。

应用场景

防抖在连续的事件,只需触发一次回调的场景有:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测
  • 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

节流在间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚到底部监听
  • 搜索框,搜索联想功能