fcp 防抖动
Debounce functions in JavaScript are higher-order functions that limit the rate at which another function gets called.
JavaScript中的反跳函数是高阶函数,它限制了另一个函数的调用速率。
A higher-order function is a function that either takes a function as an argument or returns a function as part of its return statement. Our debounce function does both.
高阶函数是将函数作为参数或将函数作为其return语句的一部分返回的函数。 我们的去抖功能会同时执行。
The most common use case for a debounce is to pass it as an argument to an event listener attached to an HTML element. To get a better understanding of what this looks like, and why it is useful, let’s look at an example.
防反跳最常见的用例是将其作为参数传递给附加到HTML元素的事件侦听器。 为了更好地理解它的外观以及它为什么有用,我们来看一个示例。
Say that you have a function named myFunc
that gets called each time you type something into an input field. After going through the requirements for your project, you decide that you want to change the experience.
假设您有一个名为myFunc
的函数,每次在输入字段中键入内容时都会调用该函数。 在完成项目的需求之后,您决定要更改体验。
Instead, you want myFunc
to execute when at least 2 seconds have passed since the last time you typed something in.
相反,您希望myFunc
在自上次键入内容以来至少经过2秒后执行。
This is where a debounce can comes into play. Instead of passing myFunc
to the event listener, you would pass in the debounce. The debounce itself would then take myFunc
as an argument, along with the number 2000.
这是防抖作用所在。 无需将myFunc
传递给事件侦听器,您可以传递反跳。 然后,反跳本身会将myFunc
与2000一起作为参数。
Now, whenever you click the button, myFunc
will only execute if at least 2 seconds have elapsed before the last time myFunc
was called.
现在,每当您单击按钮时,只有在上次调用myFunc
之前至少经过2秒, myFunc
才会执行。
如何实现去抖功能 (How to implement a debounce function)
From start to finish, it only takes 7 lines of code to implement a debounce function. The rest of this section focuses on those 7 lines of code so that we can see how our debounce function works internally.
从头到尾,仅需7行代码即可实现反跳功能。 本节的其余部分集中在这7行代码上,以便我们可以了解去抖动功能在内部的工作方式。
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
timeout = setTimeout( callback, delay );
}
}
Starting with line 1, we've declared a new function named debounce
. This new function has two parameters, callback
and delay
.
从第1行开始,我们声明了一个名为debounce
的新函数。 这个新函数有两个参数, callback
和delay
。
function debounce( callback, delay ) {
}
callback
is any function that needs to limit the number of times it executes.
callback
是任何需要限制其执行次数的函数。
delay
is the time (in milliseconds) that needs to elapse before callback
can execute again.
delay
是callback
可以再次执行之前需要经过的时间(以毫秒为单位)。
function debounce( callback, delay ) {
let timeout;
}
On line 2, we’re declaring an uninitialized variable named timeout
.This new variable holds the timeoutID
returned when we call setTimeout
later on in our debounce
function.
在第2行,我们声明命名未初始化的变量timeout
。这新的变量保存timeoutID
回来当我们调用setTimeout
我们以后debounce
功能。
function debounce( callback, delay ) {
let timeout;
return function() {
}
}
On line 3, we’re returning an anonymous function. This anonymous function will close over the timeout
variable so that we can retain access to it even after the initial call to debounce
has finished executing.
在第3行,我们返回一个匿名函数。 该匿名函数将关闭timeout
变量,以便即使在初始执行的debounce
调用完成后,我们也可以保留对其的访问。
A closure in JavaScript occurs whenever an inner function retains access to the lexical scope of its outer function, even though the outer function has finished executing. If you want to learn more about closures, you can read Chapter 7 of “You Don’t Know JS” by Kyle Simpson
只要内部函数保留对外部函数的词法范围的访问,即使外部函数已完成执行,JavaScript也会发生关闭。 如果您想了解有关闭包的更多信息,请阅读Kyle Simpson 撰写的“ You't Know JS”的第7章。
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
}
}
On line 4, we are calling the clearTimeout
method of the WindowOrWorkerGlobalScope
mixin. This will make sure that each time we call our debounce
function, timeout
is reset, and the counter can start again.
在第4行,我们正在调用WindowOrWorkerGlobalScope
mixin的clearTimeout
方法。 这样可以确保每次调用debounce
功能时,都会重置timeout
,并且计数器可以重新启动。
The WindowOrWorkerGlobalScope
mixin of JavaScript gives us access to a few well-known methods, like setTimeout
, clearTimeout
, setInterval
, clearInterval
, and fetch
.
JavaScript的WindowOrWorkerGlobalScope
混合使我们可以访问一些众所周知的方法,例如setTimeout
, clearTimeout
, setInterval
, clearInterval
和fetch
。
You can learn more about it by reading this article.
您可以通过阅读本文来了解更多信息。
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
timeout = setTimeout( callback, delay );
}
}
On line 5, we have reached the end of our debounce
function implementation.
在第5行,我们已经完成了debounce
功能实现的结尾。
That line of code does a few things. The first action is assigning a value to the timeout
variable that we declared on line 2. The value is a timeoutID
that gets returned when we call setTimeout
. This will allow us to reference the timeout created by calling setTimeout
so that we can reset it each time our debounce
function is used.
该行代码可以做一些事情。 第一个动作是为第2行中声明的timeout
变量分配一个值。该值是一个timeoutID
,当我们调用setTimeout
时将其返回。 这将允许我们引用通过调用setTimeout
创建的超时,以便我们每次使用debounce
函数时都可以将其重置。
The second action performed is calling setTimeout
. This will create a timeout that will execute callback
(the function argument passed to our debounce
function) once delay
(the number argument passed to our debounce
function) has elapsed.
执行的第二个动作是调用setTimeout
。 这将创建一个超时,一旦delay
(传递给我们的debounce
函数的number参数)过去,它将执行callback
(传递给我们的debounce
函数的函数参数)。
Since we are using a timeout, callback
will only execute if we allow the timeout to reach 0. This is where the heart of our debounce
function comes into play since we are resetting the timeout each time debounce
is called. This is what allows us to limit the execution rate of myFunc
.
由于我们正在使用超时,因此仅当我们允许超时达到0时才执行callback
这是debounce
函数的核心发挥作用的地方,因为每次调用debounce
时都会重置超时。 这就是我们可以限制myFunc
的执行速度的原因。
Lines 5 and 6 contain only brackets, so we won’t go over them.
第5行和第6行仅包含方括号,因此我们不再赘述。
That’s it. That is how our debounce
function works internally. Now let’s add on to our previous example from the beginning. We’re going to create an input field and attach an event listener with our debounce
function as one of its arguments.
而已。 这就是我们的debounce
功能在内部工作的方式。 现在,让我们从头开始添加到前面的示例中。 我们将创建一个输入字段,并使用debounce
函数作为其参数之一附加一个事件侦听器。
真实的例子 (Real World Example)
First, we need to create an input field.
首先,我们需要创建一个输入字段。
<label for="myInput">Type something in!</label>
<input id="myInput" type="text">
Next, we need to create a function that we want to execute whenever we type something into our input field.
接下来,我们需要创建一个函数,只要我们在输入字段中键入内容,便要执行该函数。
function helloWorld() {
console.log("Hello World!")
}
Finally, we need to select the input field we created above and attach a keyup
event listener to it.
最后,我们需要选择我们在上面创建的输入字段,并将keyup
事件侦听器附加到该字段。
const myInput = document.getElementById("myInput");
myInput.addEventListener(
"keyup",
debounce( helloWorld, 2000 )
);
That concludes our real world example! Each time we type something into our input field, helloWorld
will execute if at least 2 seconds have passed since the last time we typed something in.
到此结束了我们的真实示例! 每次我们在输入字段中键入内容时,如果自上次键入内容以来至少经过了2秒, helloWorld
将执行。
Special thanks to Reddit user stratoscope for helping to fix some of the initial code in this article. Here is a working demo he created of this
debounce
function on Repl.it.特别感谢Reddit用户stratoscope帮助解决了本文中的某些初始代码。 这是他在Repl.it上创建的此
debounce
功能的演示示例 。
结束语 (Closing Notes)
Debounce functions are simple, yet powerful, functions that can have a noticeable impact on most JavaScript applications.
防反跳功能既简单又强大,可以对大多数JavaScript应用程序产生明显的影响。
While our example was fun and straightforward, many large organizations use debounce functions to increase the performance of their applications.
虽然我们的示例很有趣且简单明了,但是许多大型组织都使用去抖动功能来提高其应用程序的性能。
If you want to learn more about JavaScript, check out my website! I am working on some cool stuff at https://juanmvega.com.
如果您想了解有关JavaScript的更多信息,请访问我的网站! 我正在https://juanmvega.com上研究一些很酷的东西。
fcp 防抖动