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

时间:2016-04-21 17:08:25

标签: javascript lodash debouncing

我非常感谢lodash的去抖和油门功能。我相信我很了解用例,已经实现了几十次。

但是,根据要求,具有参数的_.debounce函数可能存在重大且难以捕获的错误。这是以下内容:

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

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

子函数最终将使用参数1进行调用。这对于仅关注最后一个值的resize事件非常有用,但如果根据参数需要单独的去抖队列,该怎么办?也就是说,不是使用参数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>
&#13;
&#13;
&#13;

我在_.debounce接受了一个论点时看到了许多SO问题。这不再是一个有趣的问题,那么 - 你如何创建单独的去抖队列?

使用Lodash _.debounce函数,Lodash库和JavaScript本机功能来实现这一目标的优雅方式(简单易读的代码)是什么?也许_.debounce和_.memoize的组合(我已经尝试用_.memoize包装_.debounce但是需要探索以进一步理解memoize)。或者也许是一个散列&#39;的函数。参数并为每个参数组合创建一个新的_.debounce队列?

1 个答案:

答案 0 :(得分:2)

将不同的debounced函数存储在对象中,其中键表示参数。这在您的用例中很有效,因为参数是字符串。

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>