1

函数的节流和函数的防抖都是优化高频率执行的函数的一种方法。我们知道浏览器中某些计算和处理要比其他昂贵很多。比如DOM的操作。当一个操作dom的函数高频率执行时,我们可以根据情况进行节流或防抖的处理。

节流函数

在每个时间段里,最多只允许运行一次。比如说resize调整窗口,在调整窗口的过程中,事件一直在高频率的触发,我们可以利用节流函数让其在一定的间隔时间段内最多触发一次。用一个形象的比喻吧。生产线上的啤酒瓶排成队往前跑,一个行动迟缓的树懒,每一段时间内只能拿到一个瓶子。

思路:第一次调用的时候记录一下时间戳,之后每次运行的时候都和上一次调用的时候的时间戳比较差值,当差值大于等于某个值的时候才执行。

function throttle (action, delay) {
  let timeout = null
  let lastRun = 0
  return function () {
    if (timeout) {
      return
    }
    let elapsed = Date.now() - lastRun
    let context = this
    let args = arguments
    let runCallback = function () {
      lastRun = Date.now()
      timeout = false
      action.apply(context, args)
    }
    if (elapsed >= delay) {
      runCallback()
    } else {
      timeout = setTimeout(runCallback, delay)
    }
  }
}

防抖函数

在高频调用中,只有足够的空闲时间,代码才会执行一次,常见的就是input的change事件,只有停顿输入的事件大于指定的时间,代码才会执行一次。用一个形象的比喻吧。生活中的声控灯,只要你不停的说话,灯就不会熄灭,只有你安静的时间大于一定的值时,灯才会熄灭。

思路:第一次调用的时候创建一个定时器,在指定的间隔时间之后运行代码,当第二次调用该函数时,清除前一次的定时器并另设置一个。如果前一个定时器已经执行了,这个操作就没任何意义,如果前一个定时器还没执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。根据以上思路实现一个防抖函数。


function debounce(action, content, delay){
    let timeoutId = null;
    return function() {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(function(){
            action.apply(content);
        }, delay);
    }
}

jessezhao1990
1.5k 声望560 粉丝