节流(throttle)和去抖(debounce)的简单实现

节流(throttle)和去抖(debounce)

面试时经常会被问到,怎么去控制用户频繁的滚动,输入操作,我一般都会脱口而出,节流去抖呀,然后专业点的面试官总会接上一句:“你能自己实现一个吗?”

然后我就有点懵逼,实现起来好像也不简单啊。

不懂就来学,先找了下别人的实现,然后根据自己理解,手写了一遍,也算是弄清楚了,所以记录一下

Throttle

var throttle = function (fn, interval) {

  // 记录前一次时间
  var last = +new Date()

  var timerId = null
  // 包装完后返回 闭包函数
  return function () {
    var current = +new Date()
    var args = [].slice.call(arguments, 0)
    var context = this
    // 首先清除定时器
    clearTimeout(timerId)
    // current 与last 间隔大于interval 执行一次fn
    // 在一个周期内 last相对固定 current一直再增加
    // 这里可以保证调用很密集的情况下 current和last 必须是相隔interval 才会调用fn
    if (current - last >= interval) {
      fn.apply(context, args)
      last = current
    } else {
      // 如果没有大于间隔 添加定时器
      // 这可以保证 即使后面没有再次触发 fn也会在规定的interval后被调用
      timerId = setTimeout(function() {
        fn.apply(context, args)
        last = current
      }, interval)
    }
  }
}

Debounce

var debounce = function (fn, interval) {

  // debounce中的interval 和 throttle中的 interval含义不一样
  // 在debounce中可以可以把interval理解成 用户停止了某个连续的操作后 再推迟interval执行fn
  var timerId = null

  return function () {
    var current = +new Date()
    var args = [].slice.call(arguments, 0)
    var context = this
    // 如果调用很密集 可以保证fn永远不会触发 必须等到有前后两个调用的间隔大于等于interval fn才能被执行
    // 如果调用很少 fn会在interval结束后被执行
    clearTimeout(timerId)
    timerId = setTimeout(function() {
      fn.apply(context, args)
    }, interval)
    
  }
}

知其所以然~~

你可能感兴趣的:(节流(throttle)和去抖(debounce)的简单实现)