_.debounce는 무엇을합니까?
내가 작업 한 프로젝트는 _.debounce ()를 사용합니다.
디 바운스에 대한 Underscore JS 문서 는 다음과 같습니다.
디 바운스
_.debounce(function, wait, [immediate])
마지막으로 호출 된 이후 대기 밀리 초가 경과 할 때까지 실행을 연기 할 전달 된 함수의 새로운 디 바운스 버전을 생성하고 반환합니다 .
이것은 분명히 무엇을하는지 알고 싶어하는 사람은 debounce()
이미 '디 바운스'가 무엇을 의미하는지 알고 있다고 가정합니다 .
디 바운스는 실제로 무엇을합니까?
기본적으로 호출을 제한하므로 짧은 시간에 두 번 이상 호출되면 하나의 인스턴스 만 호출됩니다.
왜 그것을 사용합니까?
window.onresize와 같은 이벤트는 연속적으로 여러 번 실행됩니다. 새 위치에서 많은 계산을 수행해야하는 경우 계산을 여러 번 실행하고 싶지 않습니다. 사용자가 크기 조정 이벤트를 완료했을 때만 실행하려고합니다.
underscore.js 소스 코드 의 설명 :
계속 호출되는 한 트리거되지 않는 함수를 반환합니다. 함수는 N 밀리 초 동안 호출이 중지 된 후에 호출됩니다. 'immediate'가 전달되면 후행 대신 선행 에지에서 함수를 트리거합니다.
자체 코딩 :
_.debounce = function(func, wait, immediate) {
var timeout, result;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) result = func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(context, args);
return result;
};
};
저는 Demystifying Debounce in JavaScript 라는 제목의 게시물을 작성했습니다. 여기서 디 바운스 기능이 어떻게 작동하는지 정확히 설명 하고 데모를 포함했습니다.
디 바운스 함수는 함수 실행을 "조절"하는 방법을 제공합니다. 일반적으로 빠르게 연속적으로 발생하는 이벤트에 함수가 바인딩 된 상황에서 사용됩니다. 창 크기 조정 및 스크롤에 사용되는 디 바운스 기능을 보는 것은 일반적입니다.
Underscores 또는 다른 JavaScript 라이브러리에 관계없이 모든 디 바운스 기능은 JavaScript의 기본 setTimeout
메서드를 기반으로합니다. 따라서 디 바운스 기능의 기능을 이해하기 전에 (links to MDN)을 철저히 이해WindowTimers
하는 것이 좋습니다 .
또한 범위와 클로저를 잘 이해하고 싶을 것입니다. 상대적으로 크기는 작지만 디 바운스 함수는 실제로 꽤 고급 JavaScript 개념을 사용합니다!
즉, 아래는 위에서 언급 한 내 게시물에서 설명하고 데모 한 기본 디 바운스 기능입니다.
완제품
// 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);
}
};
};
제한 시간이 만료 될 때까지 함수 실행을 보류합니다. 이것은 필요하지 않을 때 함수의 지속적인 실행을 피하기위한 것입니다. underscore.debounce ()는 복잡한 코드에 의존하므로주의하십시오. 대부분의 경우 함수 내부의 간단한 "if"문이 디 바운스보다 훨씬 빠릅니다. 카운터를 구현하여 매 N 번의 반복 만 메서드를 실행하거나 시간 제한을 적용하여 최소한 일정 밀리 초가 경과했는지 확인할 수 있습니다.
참조 URL : https://stackoverflow.com/questions/15927371/what-does-debounce-do
'Programing' 카테고리의 다른 글
새 행에서 선택 가능한 영역을 작게 만들지 않고 WPF DataGrid 셀을 오른쪽 정렬하는 방법은 무엇입니까? (0) | 2020.12.24 |
---|---|
MongoDB의 기본 데이터베이스 경로는 무엇입니까? (0) | 2020.12.24 |
count (*) "column"에 별칭을 사용하고 having 절에서 참조 할 수없는 이유는 무엇입니까? (0) | 2020.12.24 |
Protobuf-net을 사용하면서 갑자기 알 수없는 와이어 유형에 대한 예외가 발생했습니다. (0) | 2020.12.24 |
목록에있는 모든 요소의 두 번째 하위 요소를 가져 오는 방법 (0) | 2020.12.24 |