Underscore debounce vs vanilla Javascript setTimeout

Underscore debounce vs vanilla Javascript setTimeout

我了解到 debounce 在 Undercore.js returns 中有一个函数会延迟执行直到等待时间结束。

我的问题是,在原版 Javascript 中使用 debounce 是否优于常规 setTimeout 函数?它们的工作原理不一样吗?

setTimeoutdebounce 绝不是一回事。 setTimeout 只需等待 n 毫秒,然后调用提供的函数。 debounce 另一方面 returns 一个仅在 n 毫秒后调用回调的函数 在最后一次调用函数后 .

巨大的差异。 Debouncing/throttling(它们不是一回事)函数通常用于减少用户输入导致的函数调用量。想象一个 autocomplete/typeahead 字段。您可能会在每次击键时都执行 ajax 请求,但这可能会有点重,因此您可以对函数进行去抖动,因此它只会在最后一次击键 触发 200 毫秒。

您可以在此处阅读文档:https://lodash.com/docs#debounce

它们非常不同,用于完全不同的情况。

  1. _.debounce returns a function, setTimeout returns an id 可以用来取消超时.

  2. 无论您调用_.debounce返回的函数多少次,在给定的时间范围内,它只会运行一次。

var log_once = _.debounce(log, 5000);

function log() {
  console.log('prints');
}

log_once();
log_once();
log_once();
log_once();
log_once();

var id = setTimeout(function() {
  console.log('hello');
}, 3000);
clearTimeout(id);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

您还可以在原版中实现自己的去抖动 JavaScript。一篇被广泛引用的文章是 David Walsh 关于 function debouncing with underscore 的文章,其中包括下划线在其实现中使用的源代码:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

debounce 函数充当您要调用的实际函数的生成器,这样状态就可以像这样在闭包内持久化:

// example function
let sayHello = (name) => console.log(`Hi ${name}`)

// generate a debounced version with a min time between calls of 2 seconds
let sayHelloDebounced = debounce(sayHello, 2000)

// call however you want
sayHelloDebounced('David')

堆栈片段中的演示

function debounce(func, wait, immediate) {
 var timeout;
 return function() {
  var context = this, args = arguments;
  var later = function() {
   timeout = null;
   if (!immediate) func.apply(context, args);
  };
  var callNow = immediate && !timeout;
  clearTimeout(timeout);
  timeout = setTimeout(later, wait);
  if (callNow) func.apply(context, args);
 };
};

let sayHello = (name) => console.log(`Hi ${name}`)

let sayHelloDebounced = debounce(sayHello, 2000)

sayHelloDebounced('David')
sayHelloDebounced('David')
sayHelloDebounced('David')

其他实现

我看到一个博客 post,其中对去抖动和节流有更清晰的解释。如果上面的答案看起来令人困惑,请检查一下。它帮助我消除了疑虑。 Debounce and Throttle in Javascript