跳到主要内容

Debounce防抖和Throttle节流

debounce(防抖)throttle(节流) 是两种常用的函数节流技术,主要用于限制函数在短时间内被频繁调用的次数。它们常用于处理那些用户可能快速连续触发、但实际上并不需要立即响应每一个触发事件的场景,比如搜索框输入实时查询、窗口滚动事件处理等,以避免不必要的计算和网络请求。

  1. Debounce(防抖): Debounce 的核心思想是,在一个事件被触发后的一段时间内(通常是一个延时时间),如果在这个时间段内再次触发了该事件,则会重新计时,只有当这个时间段结束并且没有新的触发发生时,才会执行对应的回调函数。这样可以确保一定时间段内的重复调用只会执行最后一次操作。

    例如,在用户输入搜索关键词时,使用 debounce 可以确保只有在用户停止输入一段时间(如 300 毫秒)后才发送查询请求,而不是对每一次键入都进行查询。

    function debounce(fn, delay) {
    let timer
    return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
    fn.apply(this, args)
    }, delay)
    }
    }
    const debouncedSearch = debounce(searchFunction, 300)
  2. Throttle(节流): Throttle 则是在规定的时间间隔内只允许一次函数调用。即使事件在短时间内多次触发,也会按照一定的频率去执行,而不是每次都执行。这对于保证某个动作不会过于频繁地执行非常有用,同时又能在指定时间内保持一定的更新频率。

    比如,在监听滚动事件时,我们可能希望每秒钟最多只执行一次滚动相关的计算,无论用户滚动得多快,这就可以使用 throttle 实现:

    function throttle(fn, threshhold) {
    let last, timer
    return function (...args) {
    const now = +new Date()
    if (last && now < last + threshhold) {
    clearTimeout(timer)
    timer = setTimeout(function () {
    last = now
    fn.apply(this, args)
    }, threshhold - (now - last))
    } else {
    last = now
    fn.apply(this, args)
    }
    }
    }
    const throttledScrollHandler = throttle(scrollEventHandler, 1000)

总结来说,debounce 主要用于处理连续触发且只需要最后一次有效结果的情况;而 throttle 更适用于固定时间间隔内至少执行一次,并且允许有稳定的执行频率的情况。