【问题标题】:Closure in debounce去抖中的关闭
【发布时间】:2017-10-08 15:09:33
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: javascript scope closures debounce


    【解决方案1】:

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

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

    David Walsh's article 有一个例子:

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

    注意我们这里只调用了一次debounce(),它返回的函数保存为myEfficientFn。然后在每个resize 事件上调用myEfficientFn,但传入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 );
    

    【讨论】:

    • 但是事件处理程序设置为去抖动,所以每次触发事件时,让我们说“点击”。每次点击,debounce 都会再次调用,不是吗?因为现在我将 debounce 绑定到事件处理程序。
    • 您能否在问题中添加您正在讨论的代码示例?我会看看它,看看我是否可以帮助解释它 - 或者看看你是否正确使用debounce()。我还在答案中添加了一个类似的示例。
    • @minhtran612:“因为现在我将 debounce 绑定到事件处理程序。” 这是错误的。你必须绑定debounce返回函数。
    • @MichaelGeary 非常感谢,消除了我在关闭时错过某些东西的恐惧
    猜你喜欢
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2020-11-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    相关资源
    最近更新 更多