函数防抖和函数节流原理理解

Posted suwu150

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数防抖和函数节流原理理解相关的知识,希望对你有一定的参考价值。

防抖和节流有什么用,一般的使用场景,原理是什么

1.作用

使用函数节流与函数防抖的目的,就是为了节约计算机资源,提升用户体验。

2.场景

  • 节流一般是用在必须执行这个动作,但是不能够执行太频繁的情况下,例如滚动条滚动时函数的处理,可以通过节流适当减少响应次数;

  • 防抖一般是用来,用户输入有操作时,暂时不执行动作,等待没有新操作时,进行相应响应,例如用户名输入校验的情况,可以等待用户输入完成后再发送请求去校验。

3.原理

总的来说,函数节流与函数防抖的原理非常简单,巧妙地使用 setTimeout 来存放待执行的函数,这样可以很方便的利用 clearTimeout 在合适的时机来清除待执行的函数。

  • 函数节流: 指定时间间隔内只会执行一次任务;
  • 函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

节流:等待lock的状态,如果lock状态为false,则不会再次执行语句if (!lock) return;后面的内容,直至等待setTimeout函数内容执行完毕,将lock置为true之后,才会再次执行,从而达到减少fn响应次数。

function throttle(fn, interval = 300) 
    let lock = true;
    return function () 
        if (!lock) return;
        lock = false;
        setTimeout(() => 
            fn.apply(this, arguments);
            lock = true;
        , interval);
    ;

防抖:interval时间内,如果有fn再次触发,则会清除上次的函数执行,重新设置新的延迟函数,如果超过interval事件间隔,则会执行传入的fn函数。

function debounce(fn, interval = 300) 
    let timeout = null;
    return function () 
        if (timeout) 
          clearTimeout(timeout);
        
        timeout = setTimeout(() => 
            fn.apply(this, arguments);
        , interval);
    ;

4.React Hooks中使用

在hooks中使用时,通常会是如下的用法:

export default function() 
  const [counter, setCounter] = useState(0);

  const handleClick = useDebounce(function() 
    setCounter(counter + 1)
  , 1000)

  return <div style= padding: 30 >
    <Button
      onClick=handleClick
    >click</Button>
    <div>counter</div>
  </div>


实现时,我们需要使用到hooks中的useRef进行缓存timer,通过useRef保留fn方法与timer,实现代码:

function useDebounce(fn, delay, dep = []) 
  const  current  = useRef( fn, timer: null );
  useEffect(function () 
    current.fn = fn;
  , [fn]);

  return useCallback(function f(...args) 
    if (current.timer) 
      clearTimeout(current.timer);
    
    current.timer = setTimeout(() => 
      current.fn.call(this, ...args);
    , delay);
  , dep)


同理我们直接给出useThrottle的代码:

function useThrottle(fn, delay, dep = []) 
  const  current  = useRef( fn, timer: null );
  useEffect(function () 
    current.fn = fn;
  , [fn]);

  return useCallback(function f(...args) 
    if (!current.timer) 
      current.timer = setTimeout(() => 
        delete current.timer;
      , delay);
      current.fn.call(this, ...args);
    
  , dep);



参考:
1.https://juejin.im/entry/58c0379e44d9040068dc952f
2.https://juejin.im/post/5ea04691e51d4547126400c7?utm_source=gold_browser_extension

以上是关于函数防抖和函数节流原理理解的主要内容,如果未能解决你的问题,请参考以下文章

防抖和节流

跟着大佬学JavaScript之lodash防抖节流合并

浅析函数防抖与函数节流

javascript的防抖和节流深入理解

防抖和节流原理具体实现

防抖和节流原理具体实现