concept

1. Debounce

Function buffering means that after the event is triggered, the function can only be executed once within n seconds. If the event is triggered again within N seconds, the function execution delay time is recalculated.

In layman’s terms: the trigger is repeated over a period of time, executing only the beginning and the end, or executing only the end

Use scenario: browser page onresize, Scroll, Mousemove,mousehover, etc., will be triggered frequently (triggered many times in a short period of time) when the need to use the tremble, or some click events, to prevent multiple clicks caused by frequent request background.

2. Throttle

Function throttling means that after an event is triggered, the function can be executed only once within n seconds. If an event is triggered within N seconds, the event will be executed again. As the name implies, it is like water pipe, with frequency of execution.

Colloquially speaking: trigger repeatedly within a period of time, according to a certain frequency (3s, 5s) execution, can be configured to execute once at the beginning

Usage scenarios: Browser onresize, Scroll, Mousemove,mousehover, etc. need to be throttled when they are triggered frequently (many times in a short period of time). For example, when a browser scroll event occurs, the event will be executed every 3 or 5 seconds.

use

1. Handwritten anti-shake function

Think before writing:

  1. Debounce is a function, and a function handle is passed in
  2. After passing in the function, we pass in a wait for the shake out time
  3. Determine whether to execute immediate
  4. Returns a function fn

write

function debounce(handle,wait,immediate){
    // Start with parameters
    if(typeofhandle ! = ='function') throw new Error('handle must be function')
    // The default wait is 1s
    if(typeof handle === 'undefinde') wait = 1000 
    // If only handle and immediate are passed
    if(typeof wait === 'boolean'){
        immediate = wait
        wait = 1000
    }
    //immediate is flase by default
    if(typeofimmediate ! = ='boolean') immediate = false
    // For the so-called anti-shake effect, what we want to achieve is that one person can manage the execution times of Handle
    let timer = null
    return function proxy(. args){
        let self = this, init = immediate && ! timerclearTimeout(timer)
        timer = setTimeout(() = >{
            timer = null! immediate ? handle.aplly(self,args) :null
        },
        wait)
        // If executed immediately
        init ? handle.apply(self,args) : null}}Copy the code

HTML is used in

<button type="button" id="btn1"> if < / button >// Click the function
function clickHandle(){
    console.log('Anti-shake Demonstration')}document.getElementById('btn1').addEventListener('click',debounce(clickHandle,3000.true))
Copy the code

Used in the VUE

<button type="button" @click="clickHandle"> if < / button >/ / method method
methods:{
    clickHandle: debounce(function(){
        console.log('Anti-shake Demonstration')},3000.true)}Copy the code

Handwritten throttling function

Think before writing:

  1. Debounce is a function, and a function handle is passed in
  2. After passing the function, we pass a throttling time wait
  3. Determine whether to execute immediate
  4. Returns a function fn

write

// Through the time difference
function throttle(handle,wait,immediate){
    if (typeofhandle ! = ='function') throw new Error('handle must be an function')
    if (typeof wait === 'undefined') wait = 1000
    // If only handle and immediate are passed
    if(typeof wait === 'boolean'){
        immediate = wait
        wait = 1000
    }
    //immediate is flase by default
    if(typeofimmediate ! = ='boolean') immediate = false
    // Define a variable to record the time of the last execution
    let previous = 0
    let timer = null
    return function proxy(. args){
        // Get the current time
        let now = new Date(a)let self = this
        // If not executed immediately
        if(! immediate) previous = now// Calculate the interval time
        let interval = wait - (now - previous)
        if(interval <= 0) {// This is a non-high frequency operation that can be performed
            clearTimeout(timer)
            timer = null
            handle.apply(self,args)
            previous = new Date()}else if(! timer){// When we find a timer in the system, it means we do not need to start the timer again
            // Handle should not be executed if the operation occurred within the frequency time range defined by us
            // At this point, we can define a timer and ask handle to execute it after the interval
            timer = setTimeout(() = >{
                clearTimeout(timer) // Clear the timer
                timer = null
                handle.apply(self,args)
                previous = new Date()
            },interval)
        }
    }
}
Copy the code
// Implement with timer (compact version)
function throttle(fn, wait = 1000, immediate = false) {
  let flag = true
  let timer = null
  return function(. args) {
    if (flag) {
      // Whether to execute immediately
      immediate && fn.apply(this, args)
      // Close the channel and wait for the timer to run
      flag = false
      timer = setTimeout(() = > {
        !isImmediate && fn.apply(this, args)
        flag = true
      }, wait)
    }
  }
}
Copy the code

use

Throttling and anti – shake use, refer to the above anti – shake to get used

conclusion

Anti – shake and throttling are often encountered in daily development and it is recommended that they be encapsulated in project functions. In particular, when clicking the submit button, in order to prevent the user from mistakenly clicking the submit button for multiple times, an anti-shaking function of about 1s can be added internally.