Lodash防抖功能的计时器无法正常工作

时间:2019-12-23 09:55:48

标签: javascript jquery lodash

我尝试使用lodash的_.debounce函数,如下所示:

var count = 0;
var debouncedFunction = _.debounce(() => console.log('debounce'), 500);
var timer = setInterval(() => {
  console.log('setInterval');
  count++;
  if (count === 505) {clearInterval(timer);}
}, 1);
debouncedFunction();

问题是:计时器计数到127之后,将触发反跳功能,而我希望应该在计时器计数到500后触发反跳功能。
我不知道为什么对此有任何想法。

1 个答案:

答案 0 :(得分:1)

setInterval的时间安排并不十分准确。 5-10毫秒以下的数量不是很可靠。有关该问题,请参见specification

  

此API不保证计时器会完全按计划运行。预计由于CPU负载,其他任务等导致的延迟。

即使在最佳条件下,也不应该相信超时和间隔在10毫秒内是准确的。

10毫秒可以正常工作:

// Give the browser time to finish initial load
setTimeout(() => {
  var count = 0;
  var debouncedFunction = _.debounce(() => console.log('debounce'), 500);
  var timer = setInterval(() => {
    console.log('setInterval', count);
    count += 10;
    if (count === 510) {clearInterval(timer);}
  }, 10);
  debouncedFunction();
}, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

(对我来说,{debounce在430记录时大约在运行)

20毫秒的效果更好(460或480):

// Give the browser time to finish initial load
setTimeout(() => {
  var count = 0;
  var debouncedFunction = _.debounce(() => console.log('debounce'), 500);
  var timer = setInterval(() => {
    console.log('setInterval', count);
    count += 20;
    if (count === 520) {clearInterval(timer);}
  }, 20);
  debouncedFunction();
}, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

这不是Lodash的问题,这是超时不精确的问题。

要获得更精确的计时,请频繁运行一个间隔,并使用performance.now()(或也许是Date.now())检查从间隔开始的毫秒差:

// Give the browser time to finish initial load
setTimeout(() => {
  const initial = performance.now();
  var debouncedFunction = _.debounce(() => console.log('debounce'), 500);
  var timer = setInterval(() => {
    const diff = performance.now() - initial;
    console.log('setInterval', diff);
    if (diff >= 520) {clearInterval(timer);}
  });
  debouncedFunction();
}, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>