关闭去抖动

Closure in debounce

我在读完这篇文章后偶然发现了去抖是如何工作的: Can someone explain the "debounce" function in Javascript

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

"Note that this overwrites the value of timeout and this value persists over multiple function calls!"

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

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

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

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

David Walsh's article有个例子:

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

window.addEventListener( 'resize', myEfficientFn );

注意我们这里只调用了一次debounce(),它returns一个函数,保存为myEfficientFn。然后 myEfficientFn 在每个 resize 事件上被调用,但是传递给 debounce() 的回调函数仅在 250 毫秒内没有更多 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 );