2

读完这篇文章后,我偶然发现了去抖是如何工作的: 有人可以解释 Javascript 中的“去抖”功能吗

在这个接受的答案中有一些东西我无法弄清楚它怎么会是这样的:

“请注意,这会覆盖超时值,并且该值会在多个函数调用中持续存在!”

每次调用 debounce 方法时,都会为其创建一个新堆栈,返回的函数可以访问超时值。是的,我将其理解为关闭的性质。但是在多次调用中,我们得到包装器去抖动会产生一个新的本地超时,那么如何才能清除先前调用中的超时,因为它们没有绑定到相同的超时?

非常感谢,我知道这是非常基本的 JS,但我不想忽略它,因为我知道,如果理解它,我可以了解更多关于 JS 的知识。

4

1 回答 1

6

可能让您感到困惑的是您不会debounce()重复调用。如果你这样做了,那么是的,timeout变量对于每个调用都是唯一的。

相反,您要做的是调用debounce() 一次。它返回一个函数,然后您可以重复调用该函数。因为这个函数嵌套在变量debounce()旁边timeout,所以每次调用它时,它都会使用同一个timeout变量。

David Walsh 的文章有一个例子:

var myEfficientFn = debounce( function() {
    // All the taxing stuff you do
}, 250 );

window.addEventListener( 'resize', myEfficientFn );

请注意,我们debounce()在这里只调用一次,它返回一个保存为myEfficientFn. 然后myEfficientFn在每个resize事件上调用,但传入的回调函数仅在250 毫秒debounce()内没有更多事件后调用。resize

您也可以将该代码等效地编写为:

window.addEventListener( 'resize', debounce( function() {
    // All the taxing stuff you do
}, 250 ) );

在这里,您可能看起来像是debounce()多次调用,但实际上并非如此。它只被调用一次,在你调用的时候addEventListener()。这里实际的事件监听函数不是debounce(),而是debounce() 返回的函数。

或者,为了更清楚起见,让我们逐步将其分解并使用更好的名称:

// Called after at least one resize event has fired but 250 milliseconds
// have gone by without another resize event.
function handleResizeAfterIdle() {
    // All the taxing stuff you do
}

// Create a function with debouncing that can be used as a resize event
// listener. resizeListener will be called on *every* resize event,
// but handleResizeAfterIdle will be called only after 250 milliseconds
// have elapsed with no more resize events.
var resizeListener = debounce( handleResizeAfterIdle, 250 );

// Now we can add the event listener.
window.addEventListener( 'resize', resizeListener );
于 2017-05-10T06:12:12.023 回答