函数节流(throttling) 与 防抖(debounce)

节流和防抖,是限制事件高频率触发 ,这类问题的解决方案,如,滚动条的滚动监听、频繁点击按钮、窗口缩放等,这类事件瞬间频繁触发,会导致性能飙升,程序卡顿。

节流:一个时间周期内的重复事件,仅触发一次。在连续高频触发事件时,动作会被定期执行,响应平滑。如,快速点击按钮提交网络请求,如果1s内重复点击了多次,可能会发起多次请求,节流策略会限制1s 的周期内,只会发起一次网络请求。

时间戳方式:

function throttle(fn, gapTime) {
    if (gapTime == null || gapTime == undefined) {
        gapTime = 1500
    }
    let _lastTime = null

    return function () {
        let _nowTime = + new Date()
        if (_nowTime - _lastTime > gapTime || !_lastTime) {
            fn.apply(this, arguments)   //将this和参数传给原函数
            _lastTime = _nowTime
        }
    }
}

定时器方式:

function throttle ( fn, delay){
  var timer;
  var isThrottle = false;
  return function (){
    var _this = this
    var args = arguments
    if(!isThrottle){
      isThrottle = true
      fn.apply(_this,args)
      timer = setTimeout(()=>{
        clearTimeout(timer)
        isThrottle = false
      },delay || 1000)
    }
  }
}

 

调用方式:

// 对象方法
Page({ ... handle: throttle(
function () { console.log(this) }, 500) ... })

// 事件绑定
btn.onclick = throttle( function(){}, 1000 )

 

 

防抖:事件持续触发时,会增加一个时间延迟,期间再次触发,会重置这个延迟,直到延迟结束,才会执行事件。当事件快速连续不断触发时,只会在动作结束时执行一次。如,调整窗口大小时,会频繁触发 onresize 事件,防抖策略,会限制事件在间歇的空挡期执行,或操作完之后执行。

function debounce(fn, delay) {
  let timer = null;

  return function () {
    let ctx = this;
    let args = arguments;
    
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    timer = setTimeout(function () {
      fn.apply(ctx, args);
      timer = null;
    }, delay);
  };
}

 

posted @ 2019-09-16 14:23  晨の风  阅读(374)  评论(0编辑  收藏  举报