防抖完整版

82 阅读2分钟

防抖函数,immediate为true时为立即执行

function debounce(func, wait, immediate) {
  let timeout
  return function (...args) {
    if (timeout) clearTimeout(timeout)
    if (immediate) {
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) func.apply(this, args)
    } else {
      timeout = setTimeout(() => {
        func.apply(this, args)
      }, wait)
    }
  }
}
  1. function debounce(func, wait, immediate) { ... }: 这是一个防抖函数,接受三个参数:func 表示要执行的函数,wait 表示等待的时间间隔,immediate 是一个布尔值,表示是否立即执行。
  2. let timeout: 这是用来存储定时器标识的变量,在定时器触发前可以用来清除之前的定时器。
  3. return function (...args) { ... }: 这是返回一个函数,这个函数就是防抖函数的实际执行体。这个函数使用了剩余参数(...args)来接收传递给这个函数的所有参数。
  4. if (timeout) clearTimeout(timeout): 如果之前已经有一个定时器在等待执行,这里会清除该定时器,以便重置计时。
  5. if (immediate) { ... } else { ... }: 这是一个条件分支,根据 immediate 参数的值来决定是立即执行一次函数(立即执行模式)还是在等待一段时间后执行函数(非立即执行模式)。
  6. const callNow = !timeout: 如果在立即执行模式下,这个变量表示是否可以立即执行函数。如果 timeout 不存在,意味着没有等待中的定时器,所以可以立即执行。
  7. timeout = setTimeout(() => { timeout = null; }, wait): 无论是哪种模式,都会设置一个定时器,在 wait 时间后将 timeout 重置为 null
  8. if (callNow) func.apply(this, args): 如果在立即执行模式下,且可以立即执行,就会调用传入的 func 函数,并将之前传递给防抖函数的参数传递给这个函数。
  9. timeout = setTimeout(() => { func.apply(this, args) }, wait): 如果在非立即执行模式下,会在 wait 时间后执行传入的 func 函数,并将之前传递给防抖函数的参数传递给这个函数。