Lodash _.debounce 具有唯一参数变体的单独队列

Lodash _.debounce with separate queues for unique argument variants

本文关键字:单独 队列 参数 唯一 debounce Lodash      更新时间:2023-09-26

我真的很欣赏 lodash 的去抖动和油门功能。 我相信我很好地理解了这些用例,并且已经实现了数十次。

但是,根据要求,具有参数的 _.debounce 函数可能会出现严重且难以捕获的错误。 具体如下:

假设您有一个名为 debounceFn 的去抖动函数,它接受一个参数,并且去抖间隔为 1000 毫秒。

  • 100毫秒:debounceFn(1)
  • 200毫秒:debounceFn(2)
  • 300毫秒:debounceFn(2)
  • 400毫秒:debounceFn(1)
  • 500毫秒:debounceFn(1)

子函数最终将以参数 1 调用。 这适用于只关心最后一个值的调整事件大小,但是如果您需要根据参数单独的去抖队列怎么办? 也就是说,不是用参数 1 调用的进程,而是用参数 1 和参数 2 调用进程,但只调用一次(因为它们都被去抖动)。

作为一个扩展且稍微复杂一些的示例,请考虑下面的参数组合,其中组合生成一个唯一的队列。

实际输出:

  • a: lime b: kiwi

所需输出(前两个输出的顺序可以翻转)

  • a: apple b: banana
  • a: apple b: orange
  • a: lime b: kiwi

var process = function(a, b) {
  document.writeln('a: ' + a + ' b: ' + b);
};
var debounceProcess = _.debounce(function(a, b) {
  process(a, b);
}, 1000);
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 100);
setTimeout(function() {
  debounceProcess('apple', 'banana');
}, 200);
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 300);
setTimeout(function() {
  debounceProcess('lime', 'kiwi');
}, 400);
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>

我已经看到很多关于 _.debounce 接受论点的 SO 问题。 这不再是一个有趣的问题,所以 - 如何创建单独的去抖动队列?

使用 Lodash

_.debounce 函数、Lodash 库和 JavaScript 原生功能来实现此目的的优雅方法(简单、易于阅读的代码)是什么? 也许是 _.debounce 和 _.memoize 的组合(我尝试用 _.memoize 包装 _.debounce,但需要探索以进一步理解 memoize)。 或者也许是一个函数来"散列"参数并为每个参数组合创建一个新的 _.debounce 队列?

将不同的去抖函数存储在一个对象中,其中键表示参数。这在您的用例中效果很好,因为参数是字符串。

var process = function(a, b) {
  $('body').append($('<p>').text('a: ' + a + ' b: ' + b));
};
function debounceProcess(a, b) {
  if (! debounceProcess.queues)    { debounceProcess.queues = {}; }
  if (! debounceProcess.queues[a]) { debounceProcess.queues[a] = {}; }
  if (! debounceProcess.queues[a][b]) {
    debounceProcess.queues[a][b] = _.debounce(function(a, b) {
      process(a, b);
    }, 1000);
  }
  return debounceProcess.queues[a][b](a, b);
};
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 100);
setTimeout(function() {
  debounceProcess('apple', 'banana');
}, 200);
setTimeout(function() {
  debounceProcess('apple', 'orange');
}, 300);
setTimeout(function() {
  debounceProcess('lime', 'kiwi');
}, 400);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/lodash/lodash/4.6.1/dist/lodash.min.js"></script>