防抖(debounce)和节流(throttle)

背景:
        我们在日常开发中,经常会遇到处理系统高频回调的问题,比如:scrollView 快速滚动的回调(scrollViewDidScroll),又比如用户输入文本时textView的回调(textViewDidChange),在这些场景下,为了降低CPU负担,我们一般会使用一些方法降低高频次计算,这篇文章介绍解决高频次计算的两种方法:防抖(debounce) 和 节流(throttle)。 

防抖

首先提出第一种思路,防抖:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后:

如果在200ms内,事件再次触发,当前的计时取消,重新开始计时

如果在200ms内,事件没有触发,那么执行事件的处理函数 

总结:指定时间内连续触发事件,只在最后一次事件触发结束后的指定时间之后,执行一次处理函数。

/**
 * 函数防抖
 * @param fn 函数
 * @param delay 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 */
export function _debounce(fn,delay,immediate){
  var delay = delay||200;
  var timer;
  return function(){
    var th = this;
    var args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    if(immediate){
      var callNow = !timer
      timer = setTimeout(()=>{
        timer = null;
      },delay)
      if (callNow) fn.apply(th, args)
    }else {
      timer = setTimeout(function(){
        timer = null;
        fn.apply(th,args);
      },delay)
    }
  }
}

节流

当事件第一次触发的时候,也是不立即执行函数,而是给出一个期限值比如200ms,开始计时,然后

在200ms内,再次触发的事件被全部忽略,计时结束后,执行一次函数,并且清理计时器。

200ms结束后,重新开始上述循环 

总结:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。

//节流
// 函数节流
// param fn 函数
// param interval 延迟执行毫秒数
// param type 1 表时间戳版,2 表定时器版
//时间戳和定时器区别:时间戳版本的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候

export function _throttle(fn,interval,type) {
  if(type === 1){
    let previous = 0;
  }else if(type === 2){
    let timeout;
  }
  var interval = interval || 200;
  return function () {
    var th = this;
    var args = arguments;
    if(type === 1){
      let now = Date.now();
      if (now - previous > interval){
        fn.apply(th,args);
        previous = now;
      }
    }else if(type === 2){
      if(!timeout){
        timeout = setTimeout(()=> {
          timeout = null;
          fn.apply(th,args)
        }, interval);
      }
    }
  }
}

总结:从降低CPU计算频次来说,肯定是 debounce 效果更好,因为它在整个高频回调期间,只会触发一次。

但 debounce 计算频次少,带来的影响就是可能会损失用户的体验。比如如果在 scrollViewDidScroll 中使用了 debounce 来触发某些渲染逻辑,那么用户如果一直在滚动屏幕,只有在用户松手后,才能把屏幕渲染出来,整个滚动过程是无法加载的。

考虑到现在CPU计算能力越来越强,在解决高频回调问题面前,我们可以优先选择 throttle 的方案 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KunQian_smile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值