# JS的防抖(debounce)和节流(throttle)

# 防抖(debounce)

# 非立即执行版

非立即执行版指的是事件触发之后,若wait秒内又一直触发,则将重新计时,fn 回调函数将不会触发。

function debounce(fn, wait) {
  let timer = null;
  return function() {
    // 上下文
    const context = this;
    // 参数(Array)
    const args = arguments;
    if (timer != null) {
      clearTimeout(timer);
    }
    // 
    timer = setTimeout(function() {
      fn.apply(context,args);
    }, wait);
  }
}

# 运用场景

    1. 输入框检索功能,若一直输入,则不去调用后端,等停止输入的 wait 毫秒后,才触发去调用后端接口。
    1. 窗口缩放(resize),等停止后再去处理其他事情。
    1. 表单验证,输入完后才进行校验。

# 立即执行版

立即执行版指的是事件触发后第一次马上执行,之后出若在wait秒内一直触发,则重新计时,直到wait秒后 fn 回调才会触发。

function debounce(fn, wait) {
  let timer = null
  return function() {
    const context = this
    const args = arguments
    if (timer == null) {
      fn.apply(context, args)
    } else {
      clearTimeout(timer)
    }
    timer = setTimeout(_ => {
      timer = null
    }, wait)
  }
}

# 运用场景

    1. 按钮点击提交数据事件,第一次点击马上触发,后面连续点击将无效果;直到停止wait秒后再点击就会马上触发。

# 节流(throttle)

保证一定的时间内只触发一次事件

# 非立即执行版

function throttle(fn, wait) {
  let timer = null
  return function() {
    const context = this
    const args = arguments
    if (!timer) {
      timer = setTimeout(_ => {
        fn.apply(context, args)
        timer = null
      }, wait)
    }
  }
}

# 立即执行版

function throttle(fn, wait) {
  let timer = null
  let startTime = Date.now()
  return function() {
    const context = this
    const args = arguments
    let curTime = Date.now()
    if (timer) {
      clearTimeout(timer)
    }
    // 剩余几秒
    const diffTime = wait - (curTime - startTime)
    if (diffTime <= 0) {
      fn.apply(context, args)
      startTime = Date.now()
    } else {
      // 过 剩余的几秒后执行
      timer = setTimeout(_ => {
        fn.apply(context, args)
        startTime = Date.now()
      }, diffTime)
    }
  }
}

# 应用场景

    1. 滚动条是否滑到底部,从而加载更多。
最后一次修改时间: 10/22/2020, 10:43:38 PM