防抖和节流的实现

Posted GoldenaArcher

tags:

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

防抖和节流的实现

有两种实现,第一个使用 lodash 完成,第二个自己写一个防抖/节流的操作。

本质上来说防抖和节流都是为了提升表现性能的一种方式,在前端还是属于很常见的案例。

如果没有实现防抖或节流,那么输入基本上是这样的:

如果每一次输入都会引发一次 API 调用,对于服务器的压力就会非常大。

案例中使用的是 React 进行页面渲染。

防抖(debounce)

防抖指的是让延迟事件的执行操作,如果该事件被重新触发,则延迟重置。应用案例包括不限于:搜索功能,自动保存等。

debounce - Lodash

JQuery,Lodash, underscore 等库都自带实现了 debounce 的功能,这里就以 Lodash 为例:

import  useState, useCallback  from "react";

import  debounce  from "lodash";

export default function App() 
  const [input, setInput] = useState("");

  const handleSearch = useCallback(
    debounce((value) => 
      console.log(value);
    , 500),
    []
  );

  const handleChange = (e) => 
    const  value  = e.target;
    setInput(value);
    handleSearch(value);
  ;

  return (
    <div className="App">
      <input type="text" value=input onChange=handleChange />
    </div>
  );

实现完毕后的效果:

比起没有实现 debounce 的效果,这里用户的操作会调用 2 次 API,服务器的压力一下子就减少了很多。

debounce - setTimeOut

const debounce = (cb) => 
  let timeout;
  return function () 
    clearTimeout(timeout);
    timeout = setTimeout(() => cb.apply(this, arguments), 500);
  ;
;

其原理就是每次调用 debounce 之后,之前的 timeout 会被清理掉,并且返回一个新的 timeout。在 timeout 中设定的时间间隔过去后,原本的函数被调用。

节流(throttle)

节流的设定在于一个时间段内函数只能被触发一次,这种就比较适合放在收取验证码这样的功能上。

throttle - Lodash

Lodash 封装的功能用起来都差不多,把 debounce 换成 throttle 即可:

import  useState, useCallback  from "react";
import moment from "moment";
import  throttle  from "lodash";

export default function App() 
  const [input, setInput] = useState("");

  const handleSearch = useCallback(
    throttle((value) => 
      console.log(value, moment().format("YYYY-MM-DD HH:m:ss"));
    , 500),
    []
  );

  const handleChange = (e) => 
    const  value  = e.target;
    setInput(value);
    handleSearch(value);
  ;

  return (
    <div className="App">
      <input type="text" value=input onChange=handleChange />
    </div>
  );

能够看出,每秒钟 log 函数被触发了两次。

debounce - new Date

const throttle = (cb, delay = 500) => 
  let lastCalled = 0;
  return (...args) => 
    const now = new Date().getTime();
    if (now - lastCalled < delay) return;

    lastCalled = now;
    cb(...args);
  ;
;

原理就和之前解释的一样,一个时间段内——这里默认用的 500ms——函数只能被触发一次,这样的操作也被 now - lastCalled < delay guard clause 守住。当函数被调用后,lastCalled 被更新为最近调用的时间,随后重新进行判断。

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

防抖和节流啥区别,实现一个防抖和节流

JS防抖和节流

lodash的防抖和节流方法

JS的防抖和节流

防抖和节流原理具体实现

防抖和节流原理具体实现