函数节流与防抖的实现

函数节流与函数防抖

最近由于处于互联网大厂的秋招季节,因此这些天都在看前端性能优化和算法方面的知识。在性能优化方面,看了网上的一些文章,同时看完了《高性能网站建设指南》和《高性能JavaScript》两本书,颇有收获,可以参看这篇文章,主要是一些前端性能优化方面的总结。传送门:前端性能优化最佳实践

这篇文章主要是讲函数节流与函数防抖相关知识的。虽然在上面两本书里面没有谈及这两方面的内容,但是我觉得,对JS常用事件进行节流或者防抖的处理是属于性能优化方面的。

目的

实现了这两个功能函数之后发现,节流同防抖在实现过程可能不太一样,但是目的和本质都是一样的:提高性能

相同点

节流和防抖都是采用闭包的形式来实现。这主要运用了闭包的一个特性:能够记住并访问所在的词法作用的标识符。如果对闭包不了解的可以看看这个回答:什么是闭包

用途

假如,一条河流,想检测水质问题。那么我们可以完全堵住,在某个时间段后,一次性释放。那么这些水就属于检测通过了。(这个比喻我都很迷... )

函数防抖也是大同小异。在某个特定时间后执行函数,但是在此时间段内重复调用函数的话,不会执行。只有当用户停下操作后,才会在该时间后执行此函数。

主要用于输入框keyup事件等一些需要用户输入内容的行为。

函数防抖
function debounce (fn, wait) {
    let timer = null
    return function () {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
            timer = null
            fn.apply(this, arguments)
        }, wait)
    }
}
函数节流

最简单的比喻,河流的水,如果想控制一下流量,那就可以让水流间隔的流。有点类似函数节流,间隔执行;如果完全堵住,在某个时间段后一次性释放,就是函数防抖了。

最简单的函数节流实现方式如下

function throttle (fn, wait) {
    let start = 0
    return function () {
        const curr = Date.now()
        if (curr - start < wait) return
        start = curr
        fn.apply(fn, arguments)
    }
}

假如想加一些立即执行、多少秒后必须执行,那么可以参考下面的函数

function throttle (fn, option) {
  let time = null
  let start = null
  let setting = {
    delay: 300,
    mustRunTime: 500,   // 在500内必须执行。如在resize事件时,按住不放超过500ms之后就必须执行函数。
    immediate: false
  }
  option = Object.assign({}, setting, option)
  return function () {
    let args = arguments
    let context = this
    let currStart = +new Date()
    if (!start) {
      start = currStart
    }
    let timeDiff = currStart - start
    // 初始调用resise函数时立即执行函数,而不用等待delay的时间
    if (option.immediate || timeDiff > option.mustRunTime || timeDiff > option.delay) {
      fn.apply(context, args)
      option.immediate = false
      start = currStart
    } else {
      window.clearTimeout(time)
      time = window.setTimeout(() => {
        fn.apply(context, args)
      }, option.delay)
    }
  }
}

最后

最后超简单总结下:
函数节流:间隔执行函数,主要用于keyup事件。
函数防抖:某个时间内都不执行,该时间后才执行函数,主要用于touchmove, resize等事件。

原文地址:https://www.cnblogs.com/unclekeith/p/7466205.html