【问题标题】:Underscore debounce vs vanilla Javascript setTimeoutUnderscore debounce vs vanilla Javascript setTimeout
【发布时间】:2016-08-01 14:25:08
【问题描述】:

我知道 Undercore.js 中的 debounce 返回一个函数,该函数将推迟执行,直到等待时间结束。

我的问题是,在 vanilla Javascript 中使用 debounce 是否比常规的 setTimeout 函数有优势?它们的工作方式不一样吗?

【问题讨论】:

标签: javascript underscore.js settimeout lodash delayed-execution


【解决方案1】:

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

  1. _.debounce 返回一个functionsetTimeout 返回一个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>

【讨论】:

【解决方案2】:

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

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

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

【讨论】:

  • ...除非您的事件处理程序首先取消超时,然后将其重置。然后,您实际上具有相同的行为。
【解决方案3】:

您还可以在原生 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')

其他实现

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-05
      • 2014-09-25
      • 2017-02-28
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 2021-02-19
      • 1970-01-01
      相关资源
      最近更新 更多