关闭去抖动

min*_*612 2 javascript closures scope debounce

阅读本文后,我发现去抖动是如何工作的: 有人可以解释 Javascript 中的“去抖动”功能吗?

在这个被接受的答案中有一些东西我无法弄清楚它是如何变成这样的:

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

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

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

Mic*_*ary 5

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

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

David Walsh 的文章有一个例子:

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

window.addEventListener( 'resize', myEfficientFn );
Run Code Online (Sandbox Code Playgroud)

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

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

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

在这里,您可能看起来像是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 );
Run Code Online (Sandbox Code Playgroud)

  • @minhtran612:*“因为现在我将去抖动绑定到事件处理程序。”* 那是错误的。您必须通过`debounce` 绑定*returned* 函数。 (2认同)