sourcecode

자바스크립트에서 "디바운스" 기능은 무엇입니까?

codebag 2023. 10. 15. 17:17
반응형

자바스크립트에서 "디바운스" 기능은 무엇입니까?

저는 자바스크립트의 "디바운스" 기능인 자바스크립트 디바운스 기능에 관심이 있습니다.

유감스럽게도 코드가 제가 이해할 수 있을 정도로 명확하게 설명되어 있지 않습니다.어떻게 작동합니까? (아래에 제 의견을 남겼습니다)간단히 말해서, 나는 이것이 어떻게 작동하는지 정말 이해할 수 없습니다.

   // 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엉뚱한 곳에

문제의 코드가 링크의 코드에서 약간 변경되었습니다.다 .(immediate && !timeout) 새로운 타임아웃을 만들기 에.이후에 사용하면 즉시 모드가 작동하지 않습니다.링크에서 작업 버전에 주석을 달기 위해 답변을 업데이트했습니다.

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);

할 점은 .debounce를 "닫는" 함수를 생성합니다.timeout변수가. 더timeout합니다 마다 접근 합니다.debounce그 자체가 돌아왔고, 다른 통화를 통해 변경될 수 있습니다.

에 대한 .debounce과 같습니다다.

  1. 타임아웃 없이 시작합니다.
  2. 생성된 기능이 호출되는 경우 타임아웃을 지우고 재설정합니다.
  3. 타임아웃이 되면 원래 함수를 호출합니다.

번째 는 입니다.var timeout;, 참으로 정의로운 일입니다undefined 좋게도 도.clearTimeout다 :합니다.undefined타이머 식별자는 아무 것도 하지 못하게 하고 오류 같은 것을 던지지 않게 합니다.

두 번째 포인트는 제작된 기능으로 이루어집니다.합니다)에 몇 를 저장합니다.this과.arguments변수에서 나중에 이를 사용하여 취소된 통화에 사용할 수 있습니다. 있는 시간 초과를 음우)다를 하여 시간 할 새 .setTimeout. 값은 의 값을 덮어쓰고은 여러 함수 호출에 걸쳐 지속됩니다!이렇게 하면 디바운스가 실제로 작동할 수 있습니다: 함수가 여러 번 호출되면,timeout는 새로운 타이머로 여러 번 덮어씁니다.그렇지 않은 경우, 여러 호출로 인해 여러 타이머가 시작되고 모든 타이머는 활성 상태로 유지됩니다. 호출은 단순히 지연되지만 선언되지는 않습니다.

세 번째 포인트는 타임아웃 콜백에서 이루어집니다.그것은 그것을 풉니다.timeout및 함수 합니다.

immediateflag는 함수를 타이머 에 호출해야 하는지 에 호출해야 하는지를 제어하도록 되어 있습니다.그렇다면false, 타이머를 누른 후에야 원래 함수가 호출됩니다.그렇다면true, 원래 함수가 먼저 호출되고 타이머가 작동할 때까지 더 이상 호출되지 않습니다.

저는 이, 라고 .if (immediate && !timeout)됨:timeout되었습니다에서 하는 타이머 되었습니다.setTimeout그렇게!timeout 입니다.false그 시점에서 함수를 호출할 수 없습니다.undercore.js의 현재 버전은 다음을 평가하는 검사가 약간 다른 것 같습니다.immediate && !timeout 부르기 전에setTimeout좀를 들어 하지 않아요.) (. 예를 들어 사용하지 않습니다.clearTimeout . :-)

호출된 함수는 실행되지 않습니다.이들은 실행하기 전에 구성 가능한 기간 동안 호출의 일시 중지를 기다립니다. 각 새 호출은 타이머를 다시 시작합니다.

조절 기능이 실행된 다음 구성 가능한 기간을 기다린 후 다시 실행할 수 있습니다.

디바운스는 키 누르기 이벤트에 적합합니다. 사용자가 입력을 시작한 후 일시 중지하면 모든 키 누르기를 단일 이벤트로 제출하므로 호출 처리가 줄어듭니다.

스로틀은 사용자가 설정된 기간 동안 한 번만 호출할 수 있도록 허용하는 실시간 엔드포인트에 적합합니다.

Underscore.js를 통해 구현한 내용도 확인할 수 있습니다.

저도 디바운스 기능을 처음 접했을 때 어떻게 작동하는지 완전히 이해하지 못했습니다.상대적으로 크기는 작지만, 실제로는 꽤 진보된 자바스크립트 개념들을 사용하고 있습니다!,,쇄,다를 잘 .setTimeout방법이 도움이 될 것입니다.

위에 언급한 저의 게시물에서 설명하고 데모한 기본 디바운스 기능은 아래와 같습니다.

완성품

// Create JD Object
// ----------------
var JD = {};

// Debounce Method
// ---------------
JD.debounce = function(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 || 200);
        if ( callNow ) { 
            func.apply(context, args);
        }
    };
};

설명을

// Create JD Object
// ----------------
/*
    It's a good idea to attach helper methods like `debounce` to your own 
    custom object. That way, you don't pollute the global space by 
    attaching methods to the `window` object and potentially run in to
    conflicts.
*/
var JD = {};

// Debounce Method
// ---------------
/*
    Return 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 `wait` milliseconds. If `immediate` is passed, trigger the 
    function on the leading edge, instead of the trailing.
*/
JD.debounce = function(func, wait, immediate) {
    /*
        Declare a variable named `timeout` variable that we will later use 
        to store the *timeout ID returned by the `setTimeout` function.

        *When setTimeout is called, it retuns a numeric ID. This unique ID
        can be used in conjunction with JavaScript's `clearTimeout` method 
        to prevent the code passed in the first argument of the `setTimout`
        function from being called. Note, this prevention will only occur
        if `clearTimeout` is called before the specified number of 
        milliseconds passed in the second argument of setTimeout have been
        met.
    */
    var timeout;

    /*
        Return an anomymous function that has access to the `func`
        argument of our `debounce` method through the process of closure.
    */
    return function() {

        /*
            1) Assign `this` to a variable named `context` so that the 
               `func` argument passed to our `debounce` method can be 
               called in the proper context.

            2) Assign all *arugments passed in the `func` argument of our
               `debounce` method to a variable named `args`.

            *JavaScript natively makes all arguments passed to a function
            accessible inside of the function in an array-like variable 
            named `arguments`. Assinging `arguments` to `args` combines 
            all arguments passed in the `func` argument of our `debounce` 
            method in a single variable.
        */
        var context = this,   /* 1 */
            args = arguments; /* 2 */

        /*
            Assign an anonymous function to a variable named `later`.
            This function will be passed in the first argument of the
            `setTimeout` function below.
        */
        var later = function() {
            
            /*      
                When the `later` function is called, remove the numeric ID 
                that was assigned to it by the `setTimeout` function.

                Note, by the time the `later` function is called, the
                `setTimeout` function will have returned a numeric ID to 
                the `timeout` variable. That numeric ID is removed by 
                assiging `null` to `timeout`.
            */
            timeout = null;

            /*
                If the boolean value passed in the `immediate` argument 
                of our `debouce` method is falsy, then invoke the 
                function passed in the `func` argument of our `debouce`
                method using JavaScript's *`apply` method.

                *The `apply` method allows you to call a function in an
                explicit context. The first argument defines what `this`
                should be. The second argument is passed as an array 
                containing all the arguments that should be passed to 
                `func` when it is called. Previously, we assigned `this` 
                to the `context` variable, and we assigned all arguments 
                passed in `func` to the `args` variable.
            */
            if ( !immediate ) {
                func.apply(context, args);
            }
        };

        /*
            If the value passed in the `immediate` argument of our 
            `debounce` method is truthy and the value assigned to `timeout`
            is falsy, then assign `true` to the `callNow` variable.
            Otherwise, assign `false` to the `callNow` variable.
        */
        var callNow = immediate && !timeout;

        /*
            As long as the event that our `debounce` method is bound to is 
            still firing within the `wait` period, remove the numerical ID  
            (returned to the `timeout` vaiable by `setTimeout`) from 
            JavaScript's execution queue. This prevents the function passed 
            in the `setTimeout` function from being invoked.

            Remember, the `debounce` method is intended for use on events
            that rapidly fire, ie: a window resize or scroll. The *first* 
            time the event fires, the `timeout` variable has been declared, 
            but no value has been assigned to it - it is `undefined`. 
            Therefore, nothing is removed from JavaScript's execution queue 
            because nothing has been placed in the queue - there is nothing 
            to clear.

            Below, the `timeout` variable is assigned the numerical ID 
            returned by the `setTimeout` function. So long as *subsequent* 
            events are fired before the `wait` is met, `timeout` will be 
            cleared, resulting in the function passed in the `setTimeout` 
            function being removed from the execution queue. As soon as the 
            `wait` is met, the function passed in the `setTimeout` function 
            will execute.
        */
        clearTimeout(timeout);

        /*
            Assign a `setTimout` function to the `timeout` variable we 
            previously declared. Pass the function assigned to the `later` 
            variable to the `setTimeout` function, along with the numerical 
            value assigned to the `wait` argument in our `debounce` method. 
            If no value is passed to the `wait` argument in our `debounce` 
            method, pass a value of 200 milliseconds to the `setTimeout` 
            function.  
        */
        timeout = setTimeout(later, wait || 200);

        /*
            Typically, you want the function passed in the `func` argument
            of our `debounce` method to execute once *after* the `wait` 
            period has been met for the event that our `debounce` method is 
            bound to (the trailing side). However, if you want the function 
            to execute once *before* the event has finished (on the leading 
            side), you can pass `true` in the `immediate` argument of our 
            `debounce` method.

            If `true` is passed in the `immediate` argument of our 
            `debounce` method, the value assigned to the `callNow` variable 
            declared above will be `true` only after the *first* time the 
            event that our `debounce` method is bound to has fired.

            After the first time the event is fired, the `timeout` variable
            will contain a falsey value. Therfore, the result of the 
            expression that gets assigned to the `callNow` variable is 
            `true` and the function passed in the `func` argument of our
            `debounce` method is exected in the line of code below.

            Every subsequent time the event that our `debounce` method is 
            bound to fires within the `wait` period, the `timeout` variable 
            holds the numerical ID returned from the `setTimout` function 
            assigned to it when the previous event was fired, and the 
            `debounce` method was executed.

            This means that for all subsequent events within the `wait`
            period, the `timeout` variable holds a truthy value, and the
            result of the expression that gets assigned to the `callNow`
            variable is `false`. Therefore, the function passed in the 
            `func` argument of our `debounce` method will not be executed.  

            Lastly, when the `wait` period is met and the `later` function
            that is passed in the `setTimeout` function executes, the 
            result is that it just assigns `null` to the `timeout` 
            variable. The `func` argument passed in our `debounce` method 
            will not be executed because the `if` condition inside the 
            `later` function fails. 
        */
        if ( callNow ) { 
            func.apply(context, args);
        }
    };
};

저희가 지금 Promise를 사용하고 있습니다.

제가 본 많은 구현은 문제를 지나치게 복잡하게 만들거나 다른 위생 문제를 가지고 있습니다.– 타당한 2021안 Promise다. 그리고 그럴만한 이유도 있습니다.약속은 비동기 프로그램을 정리하고 실수가 발생할 기회를 줄입니다.이 게시물에서 우리는 우리만의 것을 쓸 것입니다.debounce은 - .

  • 주어진 시간에 최대 한 가지 약속이 보류되어 있습니다(해지된 작업당).
  • 보류 중인 약속을 적절히 취소하여 메모리 유출을 방지합니다.
  • 최근의 약속만 해결하다
  • 라이브 코드 데모를 통해 적절한 행동을 시연합니다.

우리는 글을 씁니다.debouncetask되는 밀리초의 양,간,ms합니다에 합니다.t-

function debounce (task, ms) {
  let t = { promise: null, cancel: _ => void 0 }
  return async (...args) => {
    try {
      t.cancel()
      t = deferred(ms)
      await t.promise
      await task(...args)
    }
    catch (_) { /* prevent memory leak */ }
  }
}

우리는 재사용 가능한 것에 의존합니다.deferred 주는 function,다.ms밀리초 두 가지 로컬 바인딩을 소개합니다라는 두 바인딩합니다.promise그 체 ,,cancel그것-

function deferred (ms) {
  let cancel, promise = new Promise((resolve, reject) => {
    cancel = reject
    setTimeout(resolve, ms)
  })
  return { promise, cancel }
}

클릭 카운터 예제

이 첫 번째 예에서는 사용자의 클릭 수를 셀 수 있는 버튼이 있습니다.됩니다를 됩니다.debounce합니다 .

// debounce, deferred
function debounce (task, ms) { let t = { promise: null, cancel: _ => void 0 }; return async (...args) => { try { t.cancel(); t = deferred(ms); await t.promise; await task(...args); } catch (_) { console.log("cleaning up cancelled promise") } } }
function deferred (ms) { let cancel, promise = new Promise((resolve, reject) => { cancel = reject; setTimeout(resolve, ms) }); return { promise, cancel } }

// dom references
const myform = document.forms.myform
const mycounter = myform.mycounter

// event handler
function clickCounter (event) {
  mycounter.value = Number(mycounter.value) + 1
}

// debounced listener
myform.myclicker.addEventListener("click", debounce(clickCounter, 1000))
<form id="myform">
<input name="myclicker" type="button" value="click" />
<output name="mycounter">0</output>
</form>

라이브 쿼리 예제, " autocomplete"

이 두번째 예에서는 텍스트 입력이 있는 양식이 있습니다. 우리의search쿼리는 다음을 사용하여 첨부됩니다.debounce-

// debounce, deferred
function debounce (task, ms) { let t = { promise: null, cancel: _ => void 0 }; return async (...args) => { try { t.cancel(); t = deferred(ms); await t.promise; await task(...args); } catch (_) { console.log("cleaning up cancelled promise") } } }
function deferred (ms) { let cancel, promise = new Promise((resolve, reject) => { cancel = reject; setTimeout(resolve, ms) }); return { promise, cancel } }

// dom references
const myform = document.forms.myform
const myresult = myform.myresult

// event handler
function search (event) {
  myresult.value = `Searching for: ${event.target.value}`
}

// debounced listener
myform.myquery.addEventListener("keypress", debounce(search, 1000))
<form id="myform">
<input name="myquery" placeholder="Enter a query..." />
<output name="myresult"></output>
</form>

다중 디바운스, 리액트 훅 사용디바운스

다른 질의응답에서 누군가가 디바운스 취소 메커니즘을 노출하고 생성하는 것이 가능한지 묻습니다.useDebounce리액트 훅.사용.deferred위에서, 사소한 운동입니다.

// revised implementation
function debounce(task, ms) {
  let t = { promise: null, cancel: _ => void 0 }
  return [
   // ...,
    _ => t.cancel() // ✅ return cancellation mechanism
  ]
}
// revised usage
const [inc, cancel] = debounce(clickCounter, 1000) // ✅ two controls
myform.mybutton.addEventListener("click", inc)
myform.mycancel.addEventListener("click", cancel)

useDebounce입니다 -에...

function useDebounce(task, ms) {
  const [f, cancel] = debounce(task, ms)
  useEffect(_ => cancel) // ✅ auto-cancel when component unmounts
  return [f, cancel]
}

전체 데모를 보려면 원래 Q&A로 이동합니다.

간단한 디바운스 함수:

HTML:

<button id='myid'>Click me</button>

자바스크립트:

    function debounce(fn, delay) {
      let timeoutID;
      return function(...args) {
          if(timeoutID)
            clearTimeout(timeoutID);
          timeoutID = setTimeout(() => {
            fn(...args)
          }, delay);
      }
   }

document.getElementById('myid').addEventListener('click', debounce(() => {
  console.log('clicked');
}, 2000));

이는 디바운딩 함수가 처음 호출될 때 항상 실행되는 변형으로, 더 설명적으로 명명된 변수가 있습니다.

function debounce(fn, wait = 1000) {
  let debounced = false;
  let resetDebouncedTimeout = null;
  return function(...args) {
    if (!debounced) {
      debounced = true;
      fn(...args);
      resetDebouncedTimeout = setTimeout(() => {
        debounced = false;
      }, wait);
    } else {
      clearTimeout(resetDebouncedTimeout);
      resetDebouncedTimeout = setTimeout(() => {
        debounced = false;
        fn(...args);
      }, wait);
    }
  }
};

다음 작업을 수행할 수 있습니다.함수를 바로 호출하려고 하면 첫 번째 함수가 취소되고 새 함수는 지정된 시간 초과를 기다렸다가 실행해야 합니다.그래서 사실상 첫 번째 기능의 타임아웃을 취소할 방법이 필요한 겁니까?하지만 어떻게요?함수를 호출하여 반환 timeout-id를 전달한 다음 해당 ID를 새 함수로 전달할 수 있습니다.하지만 위의 솔루션은 훨씬 더 우아합니다.

이것은 효과적으로 다음을 만듭니다.timeout반환된 함수의 범위에서 사용 가능한 변수. 조정'를 정'다라고 .debounce() 그래서,서.timeout내용은 변경되지 않았으며(!), "다음 함수 호출"을 위해 계속 사용할 수 있습니다.

여기서 중요한 것은 기본적으로 크기 조정 이벤트가 있을 때마다 내부 함수를 호출한다는 것입니다.모든 크기 조정 이벤트가 배열되어 있다고 생각하면 더 명확해질 수 있습니다.

var events = ['resize', 'resize', 'resize'];
var timeout = null;
for (var i = 0; i < events.length; i++){
    if (immediate && !timeout) 
        func.apply(this, arguments);
    clearTimeout(timeout); // Does not do anything if timeout is null.
    timeout = setTimeout(function(){
        timeout = null;
        if (!immediate) 
            func.apply(this, arguments);
    }
}

있잖아요.timeout다음 반복에 사용할 수 있습니까?그리고 이름을 바꿀 이유는 없다고 생각합니다.this로.content그리고.arguments로.args.

자바스크립트의 간단한 디바운스 방법:

기본 HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Debounce Method</title>
</head>
<body>
  <button type="button" id="debounce">Debounce Method</button><br />
  <span id="message"></span>
</body>
</html>

자바스크립트 파일

var debouncebtn = document.getElementById('debounce');
  function debounce(func, delay) {
    var debounceTimer;
    return function () {
      var context = this, args = arguments;
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(function() {
        func.apply(context, args)
      }, delay);
    }
  }

드라이버코드

debouncebtn.addEventListener('click', debounce(function() {
    document.getElementById('message').innerHTML += '<br/> The button only triggers every 3 seconds how much every you fire an event';
  console.log('The button only triggers every 3 seconds how much every you fire an event');
}, 3000))

런타임 예제 JSFiddle: https://jsfiddle.net/arbaazshaikh919/d7543wqe/10/

아래는 무엇이 무엇인지 요약한 것입니다.debounce기능은 합니다. 데모와 함께 두 줄로 설명합니다.

A debouncefunction은 다음과 같은 기능을 갖습니다.

  • 첫 번째 실행 시 setTimeout 기능으로 일정 시간 후 랩핑된 기능이 실행되도록 예약합니다.
  • (이 간격 동안 다시 실행되는 경우):
    • 이전 스케줄을 삭제합니다.clearTimeOut함수)
    • 새 일정 변경(setTimeout 기능 사용)

그리고 주기는 시간의 간격이 경과하여 랩핑된 기능이 실행될 때까지 계속됩니다.

모든 의견 및 이 기사에서 발췌

function debounce(callBack, interval, leadingExecution) {

// the schedule identifier, if it's not null/undefined, a callBack function was scheduled
let timerId;

return function () {

    // Does the previous run has schedule a run
    let wasFunctionScheduled = (typeof timerId === 'number');

    // Delete the previous run (if timerId is null, it does nothing)
    clearTimeout(timerId);

    // Capture the environment (this and argument) and wraps the callback function
    let funcToDebounceThis = this, funcToDebounceArgs = arguments;
    let funcToSchedule = function () {

        // Reset/delete the schedule
        clearTimeout(timerId);
        timerId = null;

        // trailing execution happens at the end of the interval
        if (!leadingExecution) {
            // Call the original function with apply
            callBack.apply(funcToDebounceThis, funcToDebounceArgs);
        }

    }

    // Schedule a new execution at each execution
    timerId = setTimeout(funcToSchedule, interval);

    // Leading execution
    if (!wasFunctionScheduled && leadingExecution) callBack.apply(funcToDebounceThis, funcToDebounceArgs);

}

}

function onMouseMove(e) {
console.log(new Date().toLocaleString() + ": Position: x: " + e.x + ", y:" + e.y);
}

let debouncedMouseMove = debounce(onMouseMove, 500);

document.addEventListener('mousemove', debouncedMouseMove);

예를 들어, 사용자가 문장을 입력한다고 가정합니다.input초당 5자의 속도로 요소를 구성합니다. 그리고 당신은 듣고 있습니다.keyup사용자가 작성한 부분 텍스트로 API를 쿼리합니다.리소스를 절약하기 위해 각 키 입력에 대해 API를 호출하지 않고 일부 간격으로 호출하거나 키 입력이 없는 시간이 지난 후에 호출할 수 있습니다.이는 디바운싱이며 아래 GIF에 표시되어 있습니다. 콜백이 트리거될 때마다 입력이 빨간색으로 바뀝니다.

Debouncing examples

GIF는 다음과 같은 네 가지 접근 방식을 보여줍니다.

  • 비난은 금물입니다.func
  • 통화를 지연시키고 이전에 지연된 통화를 취소합니다.debounce(func, 300)
  • 가능하면 즉시 전화를 걸어 이후의 전화를 연기합니다.그렇지 않으면 통화가 지연됩니다.debounce(func, 300, { immediate: true })
  • 사용자가 일시 중지 없이 긴 문장을 입력할 경우 지속적인 피드백을 위해 지연된 간격과 일부 강제된 간격.debounce(func, 300, { interval: 1500 })

이 예를 들어,immediate=false좀 더 이해가 되지만, 단추 하나에는immediate=true말이 됩니다.

function debounce(func, delay, { immediate = false, interval = 1e30 } = {}) {
  let awaiting = false;
  let last_params, deadline_A, deadline_B = 1e30;
  async function deadlineSleep() {
    while (true) {
      if (deadline_B + delay < Date.now()) deadline_B = 1e30;
      let ms = Math.min(deadline_A, deadline_B) - Date.now();
      if (ms <= 0) return;
      await new Promise(resolve => setTimeout(resolve, ms));
    }
  }
  async function wrapper(...args) {
    last_params = { arg0: this, args };
    deadline_A = Date.now() + delay;
    if (awaiting) return;
    awaiting = true;
    if (!immediate) await deadlineSleep();
    while (last_params) {
      const { arg0, args } = last_params;
      last_params = null;
      deadline_B = Date.now() + interval;
      try { await func.apply(arg0, args); }
      catch (e) { console.error(e); }
      await deadlineSleep();
    }
    awaiting = false;
  };
  return wrapper;
}

정식으로.wrapper = debounce(func, delay, {immediate, interval})다음 규칙을 준수합니다.

  • 항상 호출func다른 규칙들을 존중하면서 마지막으로 받은 매개변수들과 함께 가능한 한 빨리.
  • 한다면func비동기식입니다. 두 번의 통화가 없습니다.func평행 운행 중입니다.
  • 마지막으로 전화를 걸었습니다.wrapper항상 호출을 트리거합니다.func.
  • 전화 안 함func한 창에 두 번 이상delay씨.
  • 지연func만약에 (또는 만약에) 마지막에immediate=true) 에 전화를 겁니다.wrapper안에 있었습니다delayms 전에그렇지 않으면 실행func즉시
  • 다음을 설명하는 지연된 통화가 있는 경우interval하고 ms,합니다를 합니다.func

react.js

  function debounce(func, delay = 600) {
    return (args) => {
      clearTimeout(timeout.current);
      timeout.current = setTimeout(() => {
        func(args);
      }, delay);
    };
  }

  const triggerSearch = debounce(handleSearch);
  // Event which triggers search.
  onSearch={(searchedValue) => {
        setSearchedText(searchedValue);// state update
        triggerSearch(searchedValue);
      }}

각 이 렌더링되고 , , , 가 포함되어 있었습니다debounce func다시 시작하고 있었습니다.

이러한 반응 동작으로 인해 활성 시간 초과가 발생하지 않았습니다.

 function debounce(func, delay = 600) {
    return (args) => {
      clearTimeout(timeout.current);
      timeout.current = setTimeout(() => {
        func(args);
      }, delay);
    };
  }
 const triggerSearch = debounce(handleSearch);

는 는 했습니다.ref이름 지어진timeout.

 const timeout = useRef();

언급URL : https://stackoverflow.com/questions/24004791/what-is-the-debounce-function-in-javascript

반응형