小编典典

有人可以解释 Javascript 中的“去抖动”功能吗

all

我对javascript中的“去抖动”功能感兴趣,写在这里:http ://davidwalsh.name/javascript-debounce-
function

不幸的是,代码解释得不够清楚,我无法理解。谁能帮我弄清楚它是如何工作的(我在下面留下了我的评论)。简而言之,我真的不明白这是如何工作的

   // Returns a function, that, as long as it continues to be invoked, will not
   // be triggered. The function will be called after it stops being called for
   // N milliseconds.


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

编辑:复制的代码片段以前callNow在错误的位置。


阅读 83

收藏
2022-08-01

共1个答案

小编典典

问题中的代码与链接中的代码略有不同。在链接中,有一个检查(immediate && !timeout)BEFORE 创建一个新的
timout。拥有它之后会导致立即模式永远不会触发。我已经更新了我的答案,以从链接中注释工作版本。

function debounce(func, wait, immediate) {

  // 'private' variable for instance

  // The returned function will be able to reference this due to closure.

  // Each call to the returned function will share this common timer.

  var timeout;



  // Calling debounce returns a new anonymous function

  return function() {

    // reference the context and args for the setTimeout function

    var context = this,

      args = arguments;



    // Should the function be called now? If immediate is true

    //   and not already in a timeout then the answer is: Yes

    var callNow = immediate && !timeout;



    // This is the basic debounce behaviour where you can call this

    //   function several times, but it will only execute once

    //   [before or after imposing a delay].

    //   Each time the returned function is called, the timer starts over.

    clearTimeout(timeout);



    // Set the new timeout

    timeout = setTimeout(function() {



      // Inside the timeout function, clear the timeout variable

      // which will let the next execution run when in 'immediate' mode

      timeout = null;



      // Check if the function already ran with the immediate flag

      if (!immediate) {

        // Call the original function with apply

        // apply lets you define the 'this' object as well as the arguments

        //    (both captured before setTimeout)

        func.apply(context, args);

      }

    }, wait);



    // Immediate mode and no wait timer? Execute the function..

    if (callNow) func.apply(context, args);

  }

}



/////////////////////////////////

// DEMO:



function onMouseMove(e){

  console.clear();

  console.log(e.x, e.y);

}



// Define the debounced function

var debouncedMouseMove = debounce(onMouseMove, 50);



// Call the debounced function on every mouse move

window.addEventListener('mousemove', debouncedMouseMove);
2022-08-01