当前位置:网站首页>2000 words to help you master anti shake and throttling
2000 words to help you master anti shake and throttling
2022-07-26 20:09:00 【Front end development driver】
Preface
Anti shake and throttling are common topics , It is often involved in both interview and actual development .
This article will introduce the concepts of anti shake and throttling 、 Application scenarios 、 Code implementation , The code implementation refers to lodash Source code , The detection of parameter type and operating environment is eliminated , Make the code simpler and easier to understand , Easy to learn and understand .
Concept and Application
Both anti shake and throttling are designed to avoid frequent code execution
Shake proof
Shake proof (debounce): The timing will start after the instruction is given , If the command is repeated within the time range , Just re time , Wait for the timing to complete before executing the code .
For example : Bus entry , Pedestrians get on the bus one after another , Suppose the waiting time is 20 second , Then there is only continuity 20 Seconds when no one gets on the bus , The bus will leave ( Execute code ).
throttle
throttle (throttle): After code execution, it goes into cooling , It will not be repeated during cooling , It will not be executed again until it cools down .
For example : The goddess licks the dog once a day , After today's reply, even if you lick the dog and send more messages , The goddess will only reply the next day ( Execute the code again ).
Application scenarios
Before talking about application scenarios , First, unify the concepts of anti shake and throttling
Throttling is anti chattering with maximum time limit
Explain it. : hypothesis 100 Give instructions continuously and frequently within seconds , Shake proof The result is 100 Seconds later , But this is extremely unfriendly to users . A maximum time limit is often added to the anti shake code , When the maximum time limit is reached , Even if the command is still issued within the waiting time , But the code also executes once . This becomes throttle .
Anti shake and throttling are generally used for Search tips 、 Page scrolling, etc
It is also used to limit the number of events that are triggered frequently and indefinitely :mousemove、scroll、resize
At present, the browser has excessive performance , For a good user experience , The above scenarios basically use throttling .
Code implementation
I also said above , The difference between anti shake and throttling is whether it has Maximum time limit
So in terms of implementation , First, implement the anti shake function , Add a maximum time limit to make it a throttling function
Before writing the code , Specify the parameters of the function to be implemented 、 Return value
- The function needs to pass in two arguments , The functions that you want to limit the frequency of execution and the delay time ( The unit is millisecond )
- The return value of a function is also a function , Is the same as the function passed in , Anti jitter function
Because three functions need to be involved in the implementation , To avoid chaos , Here is a unified title :
- The function we are about to implement , Name it
debounce, Hereinafter referred to as External function - Anti jitter function , That is, the return value of the external function , Name it
debounced, Hereinafter referred to as Anti shake function - Anti jitter functions are required , That is, the function passed in when the user calls an external function , Name it
func, Hereinafter referred to as Internal function
And for internal functions , Because its function does not execute immediately , Should not have a return value
know requestAnimationFrame
be based on setTimeout Realized anti shake / There are many throttling functions on the Internet ,lodash The source code uses requestAnimationFrame, Its performance and stability are better than setTimeout, So this article is also based on requestAnimationFrame Realization
requestAnimationFrame() You need to pass in a function as an argument , This function will be executed before the next redrawing of the browser
The browser redraws every second 60 Time , about 16ms Redraw once .
You can simply requestAnimationFrame The function is treated as a delay of 16ms Of setTimeout function
Implementation of anti shake function
The anti shake function code is implemented as follows , Each time the anti shake function is called, it will be timed again , Because it's based on requestAnimationFrame, You need to recursively start the timer
/**
* @description:
* @param {Function} func The function to be anti shake , Internal function
* @param {number} wait Waiting time
* @return {Function} Anti shake function
*/
function debounce(func, wait) {let lastArgs, // Save parameters lastThis, // preservation thistimerId, // Timer idlastCallTime // The last time the anti shake function was called // Reset timer function startTimer(pendingFunc) {// Cancel the timer that was last started cancelAnimationFrame(timerId)// Start a new timer and return to the timer idreturn requestAnimationFrame(pendingFunc)}// Whether the execution time has been detected function shouldInvoke(time) {const timeSinceLastCall = time - lastCallTime// The waiting time has exceeded since the last call of the anti shake function return timeSinceLastCall >= wait}// Call the inner function function invokeFunc() {// Get previously saved this With the parameters const args = lastArgsconst thisArg = lastThis// this And set the parameter to null , Does not affect garbage collection lastArgs = lastThis = undefinedfunc.apply(thisArg, args)}// The callback function passed into the timer // Continuously obtain the current time to determine whether the internal function should be called function timerExpired() {const time = Date.now()if (shouldInvoke(time)) {// Execute internal functions timerId = undefinedinvokeFunc()} else {// Recursively start timer timerId = startTimer(timerExpired)}}// Anti shake function returned , This function has no return value function debounced(...args) {const time = Date.now()// to update this With the parameters lastArgs = argslastThis = this// Update the time of the anti shake function call lastCallTime = time// Turn on timer timerId = startTimer(timerExpired)}return debounced
}
// Testing capabilities
let preTime = Date.now()
const func = () => {let nextTime = Date.now()console.log(nextTime - preTime)preTime = nextTime
}
const dfunc = debounce(func, 50)
dfunc()
dfunc()
// after 50ms after , Console printing 50
setTimeout(() => {dfunc()dfunc()
}, 100)
// after 150ms after , Console printing 100
Throttle function implementation
stay lodash in , The throttling function and the anti shake function share a set of codes , Only the configuration parameters are different , This article will also reuse the previous code
The throttle function has two more characteristics than the anti shake function
- The throttling function contains the maximum time limit (maxWait), This is the difference between the anti shake function and the throttling function
- Throttling functions tend to execute internal functions immediately (leading)
The complete code is as follows :
/**
* @description:
* @param {Function} func The function to be anti shake , Internal function
* @param {number} wait Waiting time
* @param {number|undefined} maxWait Maximum time limit , Some are throttling functions , If not, it is an anti shake function
* @param {boolean} leading Specifies whether to call an internal function before the delay starts , The default is not to call
* @return {Function}
*/
function debounce(func, wait, maxWait = undefined, leading = false) {let lastArgs, // Save parameters lastThis, // preservation thistimerId, // Timer idlastCallTime, // The last time the anti shake function was called lastInvokeTime // The time of the most recent call to the internal function ,0 The initial value ensures let maxing = !!maxWait // Whether the maximum waiting time is specified // The maximum time limit should not be less than the waiting time if (maxWait) {maxWait = Math.max(wait, maxWait)}// Reset timer function startTimer(pendingFunc) {cancelAnimationFrame(timerId)return requestAnimationFrame(pendingFunc)}// Whether the execution time has been detected function shouldInvoke(time) {const timeSinceLastCall = time - lastCallTimeconst timeSinceLastInvoke = time - lastInvokeTime// The last intrinsic time has not been defined ( Execute throttling function for the first time )// The waiting time has exceeded since the last call of the anti shake function ( Functions of anti shake function )// The maximum time limit is set , And the maximum time limit has been reached since the last internal function call ( Function of throttling function )return (lastInvokeTime === undefined ||timeSinceLastCall >= wait ||(maxing && timeSinceLastInvoke >= maxWait))}// Call the inner function function invokeFunc(time) {// Get previously saved this With the parameters const args = lastArgsconst thisArg = lastThis// this And set the parameter to null , Does not affect garbage collection lastArgs = lastThis = undefined// Update the call time of the latest internal function lastInvokeTime = timefunc.apply(thisArg, args)}// Continuously obtain the current time to determine whether the internal function should be called function timerExpired() {const time = Date.now()if (shouldInvoke(time)) {timerId = undefined// If the internal function has been executed immediately // If the throttling function is not called again within the waiting time // There is no need to execute the internal function again after the waiting time if (lastArgs) invokeFunc(time)} else {// Turn the timer back on timerId = startTimer(timerExpired)}}// Anti shake function returned , This function has no return value function debounced(...args) {const time = Date.now()// Here we check whether the timer should be reset const isInvoking = shouldInvoke(time)// to update this With the parameters lastArgs = argslastThis = this// Update the time of the anti shake function call lastCallTime = timeif (isInvoking) {if (timerId === undefined) {// Execute throttling function for the first time , Update internal function call time lastInvokeTime = timetimerId = startTimer(timerExpired)// testing leading attribute , Call the inner function immediately if (leading) invokeFunc(time)} else if (maxing) {// Throttling function , Execute the internal function and reset the timer timerId = startTimer(timerExpired)invokeFunc(time)}} else if (timerId === undefined) {// The internal function called the throttling function just after execution // Only turn on the timer , There is no need to update the internal function call time timerId = startTimer(timerExpired)}}return debounced
}
/**
* @description:
* @param {Function} func The function to be anti shake , Internal function
* @param {number} wait Cooling time
* @param {boolean} leading Specifies whether to call an internal function before the delay starts , Default call
* @return {Function}
*/
function throttle(func, wait, leading = true) {return debounce(func, wait, wait, leading)
}
// Testing capabilities
let preTime = Date.now()
let arr = []
const func = () => {let nextTime = Date.now()arr.push(nextTime - preTime)preTime = nextTime
}
const tfunc = throttle(func, 100, false)
let id = setInterval(tfunc, 10)
setTimeout(() => {clearInterval(id)console.log(arr) // [112, 101, 104, 103, 100, 100, 100, 101, 106, 101]
}, 1000)
Other functions are realized
Let's take a look at a business scenario Hover the mouse over the button 0.5 Seconds later, the function prompt of the button appears , There are multiple buttons , Only the function prompt of the last mouse over button is displayed , It is obvious to use anti shake to achieve
However, if the user is 0.5 Seconds from the button , The prompt should not be displayed , But the timer of the anti shake function has been set ,0.5 Seconds later, the prompt is still displayed , The obvious bug
therefore , The anti shake function should have a Cancel timer The function of
function debounce(func, wait, maxWait = undefined, leading = false) {……debounced.cancel = function () {// Clear timer if (timerId !== undefined) {cancelAnimationFrame(timerId)}// Empty variables lastArgs = lastThis = timerId = lastCallTime = lastInvokeTime = undefined}return debounced
}
Conclusion
I believe that after reading this article , You must have a deep understanding of anti shake and throttling
The code implementation in this article only extracts lodash The core part of the source code , And some modifications have been made
lodash Other configuration items and functions provided are rarely used in business , This article will not introduce , If you are interested, you can check it by yourself
If there is something incomprehensible or imprecise in the text , Welcome comments and questions .
If you like or help , I hope you can like it and pay attention to it , Encourage the author .
边栏推荐
- Leetcode daily practice - 26. Delete duplicates in an ordered array
- 【ffmpeg】给视频文件添加时间戳 汇总
- C#将PDF文件转成图片
- 京东荣获中国智能科学技术最高奖!盘点京东体系智能技术
- 移动端video兼容你需要知道的几点
- C asynchronous programming read this article is enough
- Live video source code to achieve the advertising effect of scrolling up and down
- [PHP] use file_ get_ Contents() sends get and post requests
- Jincang database kingbasees SQL language reference manual (21. Kes regular expression support)
- 阿里三面:MQ 消息丢失、重复、积压问题,如何解决?
猜你喜欢

中天钢铁在 GPS、 AIS 调度中使用 TDengine

【Android】Kotlin 快速编译背后的黑科技,了解一下~

千亿酸奶赛道,乳企巨头和新品牌打响拉锯战

eadiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to c

Leetcode daily practice - 189. Rotation array
[cache series] advantages, disadvantages and choices of several cache read-write schemes

2022/07/26 learning notes (day16) abstraction and interface

DOM case: 10 second countdown - write jump page related knowledge

UE5编辑器Slate快速入门【开篇】

Three paradigms of database design
随机推荐
计算机组成原理常见面试题目总结,含答案
LeetCode_回溯_中等_216.组合总和 III
Kingbasees SQL language reference manual of Jincang database (12. SQL statement: alter language to alter subscription)
LeetCode_回溯_中等_40.组合总和 II
十大排序详解
Leetcode daily practice - 27. Remove elements
福建争抢VC/PE
Kingbases SQL language reference manual of Jincang database (15. SQL statement: create materialized view to create schema)
Zhongtian steel uses tdengine in GPS and AIS scheduling
金仓数据库 KingbaseES SQL 语言参考手册 (15. SQL语句:CREATE MATERIALIZED VIEW 到 CREATE SCHEMA)
TableWidget
C#将PDF文件转成图片
Jincang database kingbasees SQL language reference manual (18. SQL statement: drop materialized view to drop synonym)
直播预约有奖| 高级咨询顾问徐雁斐:效能度量如何助力高效精细的外包管理
Decompile jar files (idea environment)
金仓数据库 KingbaseES SQL 语言参考手册 (13. SQL语句:ALTER SYNONYM 到 COMMENT)
开源 | AREX-携程无代码侵入的流量回放实践
中天钢铁在 GPS、 AIS 调度中使用 TDengine
C# .net 时间戳和时间转换 支持时区
几张图帮你捋清“中国金融机构体系”