Writing in the front
The idea and implementation of anti-shake and throttling are relatively simple, and the concept of closure is clarified in the implementation process. However, when used in vUE project, there were some problems, such as not calling correctly, not using singletons and so on. After understanding, write down how to use it
1. Debounce
1. The function is executed only once within n seconds after the high-frequency event is triggered. If the high-frequency event is triggered again within n seconds, the time is recalculated.
To put it simply, no matter how many clicks are made within a certain period of time, only the last call will be made. The ones in front will be cleared
2. Direct implementation in methods
debounce (func, delay = 1000, immediate = false) {
/ / closures
let timer = null
// Arrow functions cannot be used
return function () {
if (timer) {
clearTimeout(timer)
}
if(immediate && ! timer) { func.apply(this.arguments)
}
timer = setTimeout(() = > {
func.apply(this.arguments)
}, delay)
}
},
Copy the code
Use 3.
<template>
<el-input v-model="text" @input="debounceInput" />
</template>
<script>
export default {
mounted () {
this.debounceInput = this.debounce(this.handle, 1000.false)
},
data () {
return {
text: ' '.debounceInput: () = >{},}},methods: {
handle (value) {
console.log(value)
},
debounce (func, delay = 1000, immediate = false) {
let timer = null
// Arrow functions cannot be used
return function () {
// The previous scheduled tasks need to be cleared when repeated calls are made in time
if (timer) {
clearTimeout(timer)
}
// For the first time to execute immediately
if(immediate && ! timer) { func.apply(this.arguments)
}
timer = setTimeout(() = > {
func.apply(this.arguments)
}, delay)
}
},
}
}
</script>
Copy the code
4. The rendering
Ii. Throttle
1. After a high-frequency event is triggered, the function is executed only once within n seconds
To put it simply, no matter how many times you click within a certain period of time, only the first time will be executed and the rest will return directly
2. Implement in utils.js (timestamp version)
export const throttle = (fn, delay = 1000) = > {
// Since last execution time
let lastTime = 0
return function () {
let _this = this
let _arguments = arguments
let now = new Date().getTime()
// Can be executed again if the delay has exceeded the previous execution
if(now - lastTime > delay){
fn.apply(_this,_arguments)
lastTime = now
}
}
}
Copy the code
3. Introduce it into VUE
<template>
<el-input v-model="text" @input="throttleInput" />
</template>
<script>
import {throttle} from '.. /utils'
export default {
name: 'throttle',
data () {
return {
text: ' ',}},methods: {
handle (value) {
console.log(value)
},
throttleInput: throttle(function (. args) {
this.handle(... args) }) } }</script>
Copy the code
4. The rendering
There is a slight flaw in this throttling effect. If the time difference between the last execution and the next user input is within the delay, the input result will not be printed
Third, optimization of throttling
- If the time difference between the last execution and the next user operation is within the delay, the operation will be abandoned. Therefore, we need to generate a timer within this period to ensure that the operation will be executed. If the delay time is exceeded, the operation can be directly executed
export const throttle = (fn, delay = 2000) = > {
let lastTime = 0, timer = null
return function () {
let _this = this
let _arguments = arguments
let now = new Date().getTime()
clearTimeout(timer)
// Determine whether the difference between the last triggering time and the current triggering time is smaller than delay and create a timer
if (now - lastTime < delay) {
timer = setTimeout(function () {
lastTime = now
console.log("Actuator trigger")
fn.apply(_this, _arguments)
}, delay)
} else {
// Otherwise, it can be executed directly
lastTime = now
console.log("Direct trigger")
fn.apply(_this, _arguments)
}
}
}
Copy the code
- rendering
Finally: closures
I have seen the concept of closure before, but the literal translation is confusing and various explanations are complicated. Now I have realized what closure is. In Java, for example, a closure is a private variable that can be accessed through a public method.