使用 lodash 忽略除最后一个调用之外的所有调用来消除抖动

Abd*_*UMI 5 javascript debouncing

如果我有一个功能foo。它会在短时间内收到许多呼叫。

function foo(name) {
  console.log(`Hi ${name}, it is now: `, new Date());
}
Run Code Online (Sandbox Code Playgroud)

使用 lodash 延迟连续函数调用( debounce )工作正常。

   const debouncedFoo = _.debounce(foo, 1000 );
Run Code Online (Sandbox Code Playgroud)

但是,我的目标是即使超时 ( 1000) 已经过去也不执行整个调用队列,并且考虑要执行的最后一次调用

换句话说,如果我debouncedFoo在 900 毫秒内调用了5 次(小于“等待参数”1000 毫秒),我只想foo被执行一次,这是最后一次 (5??) 调用。

阅读 lodash 文档,我知道它debounce被 3 重载了??参数是选项。我使用了它们,但没有发生预期的行为:

   // first attempt
  const debouncedFoo = _.debounce(foo, 1000, {leading: true} );
  // second attempt
  const debouncedFoo = _.debounce(foo, 1000, {trailing: false} );
Run Code Online (Sandbox Code Playgroud)

小智 14

就像 @AndyO 提到的那样,确保您不会在每次状态更改时重新创建去抖函数。

我也遇到了同样的问题,所以我曾经useCallback解决过它。

import React, { useCallback } from 'React';
import { debounce } from 'lodash';

const myFunction = () => { // some logic };
const debouncedMyFunction = useCallback(debounce(myFunction, 300), []);
Run Code Online (Sandbox Code Playgroud)

编辑:

如果您已经在使用callback,请检查依赖项,如果依赖项正在更改,则callback每次更新时都会创建一个新的依赖项。删除此类依赖项并将它们作为参数传递给您的函数。

  • 可以通过使用 `useMemo()` 而不是 `useCallback` 来优化此代码片段:useCallback 会导致在每次渲染时调用 debounce(),因为 useCallback 将确保向第一个 debounce() 调用返回相同的引用(除非依赖关系发生变化)。因此,虽然 useCallback 将为您带来所需的效果(相同的函数引用第一个 debounce() 调用的结果),但在这里使用 useMemo() 通常更好,因为 useMemo 只会在初始渲染期间调用 debounce()成分。示例:`const debouncedMyFunction = useMemo( () => debounce(myFunction, 300), []);` (3认同)

Der*_*會功夫 4

不熟悉 lodash,但您可以轻松实现该行为:

function debounce(cb, duration) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      cb(...args);
    }, duration);
  };
}
Run Code Online (Sandbox Code Playgroud)

function debounce(cb, duration) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      cb(...args);
    }, duration);
  };
}
Run Code Online (Sandbox Code Playgroud)