Principle: In certain situations, such as rolling, unblur, and quick click, when the event is not frequently triggered, the anti-shake function is needed to control the end of event triggering, and then the corresponding callback is executed only once. Closure is used to store the timer value. If you do not understand closures you can see closure details juejin.cn/post/684490…

Simple anti – shake function

// func callback function delay delay ms
export default function(func,delay){
    // This refers to undefined because es6 module syntax is used
    let timer
    return function(){
        // This refers to the caller window or vue instance
        let that = this
        clearTimeout(timer)
        timer = setTimeout(() = >{
            func.apply(that)        
        })            
    }
}
Copy the code

A slightly more complex anti – shake function

    // func callback function delay ms immediate Whether to execute immediately
export default function(func, delay=1000, immediate = false){
    let timer
    console.log(this)
    return function(. args){
        let that = this
        if(immediate){
            func.apply(that,args)
            immediate = false
            return
        }
        clearTimeout(timer)
        timer = setTimeout(() = >{
            func.apply(that,args)
        },delay)
    }
}
Copy the code

Ts version of the anti – shake function

/** ** function *@param Func executes the function *@param Delay Delay time ms *@param Immediate Indicates whether to execute */ immediately
export default function (func: Function, delay: number, immediate: boolean = false) :Function {
  let timer: number | undefined

  return function (this: unknown, ... args:any[]) {
    let that = this
    if (immediate) {
      func.apply(that, args) // Make sure that the reference function points correctly and that its arguments remain the same
      immediate = false
      return
    }
    clearTimeout(timer)
    timer = setTimeout(() = > {
      func.apply(that, args)
    }, delay)
  }
}
Copy the code

Anti – shake throttling integrated function

export default function (func,delay,options){
    let timer
    let defaultOption = {
        debounce:true.trailing: true.leading: false,}}Copy the code

Anti-shake functions are used in VUE

<template> <div> <h3>This is demo1</h3> <p> test debounce <button type="button" @click="noDeounceFunc($event,' noDebounce')">noDeounce</button> <button type="button" @click="debounceFunc($event,' Debonce')">debounce</button> </p> </div> </template> <script> import debounce from ".. /utils/debounce.js"; export default { methods: { debounceFunc:debounce((event,msg)=>{ console.log(msg); }, 2000), noDeounceFunc:(event,msg)=> { console.log(msg); }}}; </script>Copy the code

When leading is true, delay triggers the time every time. Otherwise, it has the same effect as anti-shake

export function debounce(func,delay,option){
    return base(func,delay,Object.assign({},{
        debounce:true,
    },option))
}

export function throttle(func,delay,option){
    return base(func,delay,Object.assign({},,{leading:true.debounce:false}option))
}

function base (func,delay = 2000,option){
    let timer
    let lastExecTime = 0
    let defaultOption = {
        leading: false.debounce: false.trailing: true,}const {leading, debounce, trailing} = Object.assign({},defaultOption,option);
    return function(. args){
        const that = this
        const previous = +new Date() - lastExecTime
        let isNotLeading = true
        function exec(){
            lastExecTime = +new Date()
            func.apply(that,args)
        }

        function clear(){
            timer = null
            exec()
        }

        if(leading && ((! debounce && previous > delay) || (debounce && timer ===null))) {
            exec()
            isNotLeading = false
          }

        if(timer){
            clearTimeout(timer)
        }

        if(trailing && isNotLeading){
            console.log(isNotLeading)
            timer = setTimeout(debounce? clear: exec,delay)
        }
    }
}
Copy the code