zhangdizhangdi

节流、防抖

防抖

最后一次触发时执行

ts
function debounce(fn: any, delay = 500) {
  let timer = null
  return function () {
    // console.log('argumentsddddd', arguments) // [InputEvent...],是oninput的arguments
    // console.log('thisddddd', this) // Proxy 组件

    const args = arguments
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

function _onInput(e: InputEvent) {
  inputVal.value = (e.target as HTMLInputElement).value
}

const onInput = debounce((e: InputEvent) => _onInput(e))

节流

规定时间内执行一次

ts
function throttle(fn: any, duration = 500) {
  let timer = null
  return function () {
    if (!timer) {
      fn.apply(this, arguments)
      timer = setTimeout(() => {
        timer = null
      }, duration)
    }
  }
}

const onScroll = throttle(function () {
  const scrollTop = document.documentElement.scrollTop
  console.log('当前滚动到:', scrollTop)
})
document.addEventListener('scroll', onScroll)

onBeforeUnmount(() => {
  document.removeEventListener('scroll', onScroll)
})

最后一次必须执行的实现

ts
function throttle2(fn: any, duration = 500) {
  let pre = 0,
    timer = null
  return function () {
    const args = arguments
    const now = Date.now()
    if (now - pre >= duration) {
      console.log('onScroll2 时间间隔', now - pre)
      fn.apply(this, args) //执行
      pre = now
    }

    //最后一次执行
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      console.log('onScroll2 timeout')
      fn.apply(this, args)
    }, duration)
  }
}

const onScroll2 = throttle2(function () {
  const scrollTop = document.documentElement.scrollTop
  console.log('onScroll2 当前滚动到:', scrollTop)
})
document.addEventListener('scroll', onScroll2)

onBeforeUnmount(() => {
  document.removeEventListener('scroll', onScroll2)
})

参考