Javascript 黛博斯是干什么的?
我一直在做的一个项目使用了u.debounce() 全文如下: 去盎司Javascript 黛博斯是干什么的?,javascript,underscore.js,Javascript,Underscore.js,我一直在做的一个项目使用了u.debounce() 全文如下: 去盎司\u.去盎司(函数,等待,[立即]) 创建并返回传递函数的新取消公告版本 这会将其执行推迟到等待毫秒之后 自上次调用以来已过 这显然是假设任何想知道debounce()做什么的人都已经知道“debounce”是什么意思了。 debounce实际上做什么?基本上它会限制调用,因此如果在短时间内多次调用它,则只会调用一个实例 你为什么要用它 类似window.onresize的事件会快速连续触发多次。如果您需要对新职位进行大量计算
\u.去盎司(函数,等待,[立即])
创建并返回传递函数的新取消公告版本
这会将其执行推迟到等待毫秒之后
自上次调用以来已过
这显然是假设任何想知道debounce()做什么的人都已经知道“debounce”是什么意思了。
debounce实际上做什么?基本上它会限制调用,因此如果在短时间内多次调用它,则只会调用一个实例 你为什么要用它 类似window.onresize的事件会快速连续触发多次。如果您需要对新职位进行大量计算,则不希望多次启动计算。您只想在用户完成调整大小事件后触发它。下划线.js中的描述: 返回一个函数,只要该函数继续被调用,它将 不会被触发。函数停止运行后将被调用 呼叫N毫秒。如果传递了“立即”,则触发 作用于前缘,而不是后缘 自我编码:
\uu0.debounce=函数(func、wait、immediate){
var超时,结果;
返回函数(){
var context=this,args=arguments;
var later=function(){
超时=空;
如果(!immediate)result=func.apply(上下文,参数);
};
var callNow=立即&&!超时;
clearTimeout(超时);
超时=设置超时(稍后,等待);
如果(callNow)结果=函数应用(上下文,参数);
返回结果;
};
};
我写了一篇题为“用JavaScript解谜”的帖子,在这里我做了详细解释,并提供了一个演示
解盎司函数提供了一种“限制”函数执行的方法。它们通常用于函数绑定到快速连续触发的事件的情况。在窗口调整大小和滚动时,通常会看到使用去盎司功能
无论是下划线还是其他JavaScript库,所有的去盎司函数都是基于JavaScript的本机setTimeout
方法构建的。因此,在深入理解去盎司函数的作用之前,最好先进行一次彻底的分析(链接到MDN)
此外,您还需要很好地理解范围和闭包。虽然debounce函数的大小相对较小,但实际上使用了一些非常高级的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);
}
};
};
它保持函数的执行,直到超时过期。这是为了避免在不需要时连续执行函数。 注意,因为下划线.debounce()依赖于复杂的代码。大多数情况下,函数中一个简单的“if”语句要比debounce快得多。
您可以实现一个计数器,只在每N次迭代中执行一个方法,或者执行一个超时,检查是否至少经过了一定数量的毫秒“返回一个函数,该函数只要继续被调用,就不会被触发。函数停止调用N毫秒后将被调用。如果传递了
immediate
,则在前缘而不是后缘触发该函数。“旁注:谷歌javascript去Bounce
将此作为第二次点击:。我创建了一个快速小提琴,演示了油门和去Bounce之间的区别。点击按钮应该可以清楚地显示每个按钮的作用,这反过来应该可以让人知道每个按钮何时合适。我建议参考一个具体的或更可靠的链接。通过引用主分支,当添加新提交时,您将得到一个不准确的锚。@RobW将其更改为最近的提交。谢谢@JackPoint。我希望他们能从(显然质量更好的)源评论中生成站点文档。这个答案是错误的,@epascarello给出的定义是针对throttle
,而不是debounce
: