跳至主要內容

11. 函数节流

鸭梨小于 1 分钟

11. 函数节流

触发高频事件,且 NN 秒内只执行一次。

11.1 简单版

  1. 使用时间戳来实现,立即执行一次,此后的 NN 秒不执行。

     * @param {number} wait
     */
    export function throttle(func, wait) {
      let previous = 0
      return function () {
        const now = new Date().getTime()
        const context = this
        const args = arguments
        if (now - previous > wait) {
          func.apply(context, args)
          previous = now
        }
      }
    }
    
  2. 使用 setTimeout 来实现,每隔 delay秒执行一次

    @[code js](./src/11-throttle-2.js

11.2 最

  • 支持取消节流
    ptioptio ,默认是 true
    • opitons.trailing 表示结束调用的时候是否还要执行一次,默认都是 false

注意同时将 leadingtrailing 设置为 false 时不能发生任何事情。

 * @param {{leading?: boolean, trailing?: boolean}?} options
 */
export function throttle(func, wait, options) {
  let timeout, context, args
  let previous = 0
  if (!options)
    options = {}
  if (!options.leading)
    options.leading = true

  const later = function () {
    previous = !options.leading ? 0 : new Date().getTime()
    timeout = null
    func.apply(context, args)
    if (!timeout)
      context = args = null
  }

  const throttled = function () {
    const now = new Date().getTime()
    if (!previous && !options.leading)
      previous = now
    const remaining = wait - (now - previous)
    context = this
    args = arguments
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }
      previous = now
      func.apply(context, args)
      if (!timeout)
        context = args = null
    }
    else if (!timeout && options.trailing) {
      timeout = setTimeout(later, remaining)
    }
  }

  throttled.cancel = function () {
    clearTimeout(timeout)
    previous = 0
    timeout = null