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

Posted

技术标签:

【中文标题】Lodash _.debounce 具有用于独特参数变体的单独队列【英文标题】:Lodash _.debounce with separate queues for unique argument variants 【发布时间】:2016-08-15 01:08:49 【问题描述】:

我非常感谢 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 的组合(我曾尝试将 _.debounce 与 _.memoize 包装,但需要进一步探索以了解 memoize)。或者也许是一个函数来“散列”参数并为每个参数组合创建一个新的 _.debounce 队列?

【问题讨论】:

【参考方案1】:

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

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>

【讨论】:

哇!摇滚。让我稍微解释一下。在这种情况下,debounceProcess 是一个尚未初始化的局部变量,对吧?或者这是从函数绑定到this 的一种方式? debounceProcess 是一个函数。函数也是 Javascript 中的对象,因此您可以为其分配属性。在这里,我分配了属性debounceProcess.queues。我根本没有使用this。我已经编辑了我的答案以使用函数声明 function debounceProcess() ... 而不是函数表达式 var debounceProcess = function() ... 以使这一点更清楚。 debounceProcess[a][b]也是一个函数,每对a,b只初始化一次。 优秀的答案!很高兴知道设置属性分配,我从来没有想过这样做。为了其他审阅者,jQuery 当然不是必需的,但为了附加元素(为了让其他审阅者清楚)而包含在内。感谢您的精彩回答! :) 能否请您也为 express/nodejs 应用发布一个 es6 等效代码?

以上是关于Lodash _.debounce 具有用于独特参数变体的单独队列的主要内容,如果未能解决你的问题,请参考以下文章

如何正确使用带有 lodash debounce 的 Vue JS 手表

lodash入门,使用 。throttle和debounce

react函数式组件中使用lodash的debounce

react 中使用 lodash 中的 _.throttle

Lodash Debounce 和 Apollo Client 使用LazyQuery 去抖动一次

Lodash 之 debounce