我正在尝试执行反跳功能,但我不明白为什么它不反跳。

我首先在这里创建此函数:



const debounce = function throttleFunctionCalls(func, wait, immediate) {
  let timeout
  return () => {
    const context = this
    const args = arguments
    const later = () => {
      timeout = null
      if (!immediate) func.apply(context, args)
    }
    const callNow = immediate && !timeout
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)
    if (callNow) func.apply(context, args)
  }
}

const testFunction = () => console.log('test')

setInterval(() => debounce(testFunction(), 10000), 100)





但是,它每100毫秒记录一次,因此无法正常工作。

我尝试了一个完全不同的debounce函数,由于分散了args而不是使用arguments,因此可以说是更好的方法,但是它遇到了同样的问题:



function debounce(func, wait) {
  let timeout
  return function throttleFunctionCalls(...args) {
    const context = this
    clearTimeout(timeout)
    timeout = setTimeout(() => func.apply(context, args), wait)
  }
}

const testFunction = () => console.log('test')

setInterval(() => debounce(testFunction(), 10000), 100)





我现在没有实际的防弹场景,因此在其自然栖息地进行测试时遇到了麻烦。

setInterval方法有什么问题吗?

似乎它对timeout的意识每次都消失了。谁能阐明一些想法?

[编辑]

正如charlietfl在下面的评论中指出的那样,我不应该引起这个功能。糟糕,我绝对不应该这样做,但是在提出这个问题之前我尝试了一下,但是没有成功,所以出于某种原因,我最终还是接受了上面的内容。



function debounce(func, wait) {
  let timeout
  return function throttleFunctionCalls(...args) {
    const context = this
    clearTimeout(timeout)
    timeout = setTimeout(() => func.apply(context, args), wait)
  }
}

const testFunction = (value) => console.log('test: ' + value)

setInterval(() => debounce(testFunction, 1), 100)





当我只是将引用函数作为引用传递时,以上内容将线程挂起。我也不确定如何将实际的函数参数传递给它,除非它通过闭包来获取它们。

谁能给我展示一个可以通过testFunction()传递任意值的函数示例?

最佳答案

让我们看一下您的最后一个示例:

function debounce(func, wait) {
  let timeout
  return function throttleFunctionCalls(...args) {
    const context = this
    clearTimeout(timeout)
    timeout = setTimeout(() => func.apply(context, args), wait)
  }
}


您已经定义了一个函数debounce,该函数接受一个函数和一个等待时间并返回一个函数。到现在为止还挺好。

const testFunction = (value) => console.log('test: ' + value)


接下来,您定义了一个函数testFunction,该函数接受一个值并将其记录下来。

setInterval(() => debounce(testFunction, 1), 100)


这是个问题。作为setInterval的第一个参数,您创建了一个新函数,该函数不接受任何参数,并返回在debounce上调用testFunction的结果。如上所述,debounce将仅返回一个函数。实际上,每100毫秒一次,您只是返回一个新函数,而不是执行日志记录逻辑。

这是使用箭头功能的代码精简版:

const debounce = (func, wait) => {
    let timeout;
    return (...args) => {
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(this, args), wait);
    };
};


再次,我们将构造一个测试函数:

const testFunction = (value) => {
    console.log(`test: ${value}`);
};


这次,我们将以1ms的等待时间制作一个去抖动的测试函数版本:

const debouncedTest1 = debounce(testFunction, 1);


现在我们可以设置一个间隔来执行它。这也是将参数传递给测试函数的方法之一:

setInterval(debouncedTest1, 200, 'foo');


这将每200毫秒记录一次“ foo”。从技术上讲,第一个日志消息将在setInterval调用后201毫秒出现:间隔为200毫秒,反跳逻辑为1毫秒。由于间隔时间大于防抖等待时间,因此此处不会发生防抖。

尝试其他方法将不会输出任何内容:

const debouncedTest2 = debounce(testFunction, 200);
setInterval(debouncedTest2, 1, 'bar');


1毫秒后,间隔超时将尝试调用debouncedTest2。防反跳逻辑将使其开始等待200毫秒,然后再执行日志。但是1毫秒后,下一个间隔超时将触发,这将再次推回该去抖动间隔。这将无限期地继续,并且您永远不会看到任何消息。

实际上,尝试用setInterval测试去抖动可能不是最好的方法。

让我们尝试一个更易于观察的等待时间,然后快速连续几次手动调用去抖动的函数:

const debouncedTest3 = debounce(testFunction, 1000);

debouncedTest3('hi');
debouncedTest3('hello');
debouncedTest3('hey');


如果尝试运行此测试,它将等待大约一秒钟,然后输出test: hey。前两个呼叫被反跳逻辑丢弃。

在切线上,将参数传递给测试函数的另一种方法是将其烘焙到去抖动的函数调用中。您可以采用多种方法来解决此问题。这是两个示例:

const debouncedTest4 = debounce(testFunction, 1000);
const debouncedTest4WithArg = () => debouncedTest4('test arg');

debouncedTest4WithArg();
debouncedTest4WithArg();
debouncedTest4WithArg();

const debouncedTest5 = debounce(() => testFunction('test arg'), 1000);

debouncedTest5();
debouncedTest5();
debouncedTest5();

关于javascript - 为什么此反跳功能不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47425026/

10-12 12:31