手写篇——防抖节流续

50 阅读1分钟

自定义属于你自己的防抖节流函数,例如:

  • 防抖函数,第一次触发事件,立即执行响应事件函数

  • 节流函数,最后一次触发事件函数,不再执行响应事件函数

借助vue的customRef的特性,实现响应式的数据

export default function (value) {
      let timer = null
      return customRef((track, trigger) => {
            return {
                  get() {
                        track()
                        return value
                  }
                  set(newValue) {
                        clearInterval(timer)
                        timer = setTimeout(() => {
                              value = newValue
                              trigger()
                        }, 1000)
                  }
            }
      })
}

自定义多功能的throttle函数

 <script>
       function ppthrottle(fn, interval,trailing = true) {
        let startTime = 0
        let timer = null

            const _throttle = function(...args) {
                let nowTime = new Date().getTime()
                let waiteTime = interval - ( nowTime - startTime) 
                    if(waiteTime <= 0 ) {
                        fn.apply(this,args)
                        if(timer)clearTimeout(timer)
                            startTime = nowTime
                            timer = null
                        return
                    }
                    if(trailing && !timer){
                        timer = setTimeout(() => {
                            fn.apply(this,args)
                            startTime = new Date().getTime()//重新设置最新的时间
                            timer = null
                        },waiteTime)
                     }
                }
                _throttle.cancel = function() {
                    if(timer) clearTimeout(timer)
            }
            return _throttle
       }
       const inputEl = document.querySelector('input')
       const  buttonEl = document.querySelector('button')
       const throttleFn = ppthrottle(function(event) {
            console.log(this.value, event)
       },3000)
       inputEl.oninput = throttleFn
       buttonEl.onclick = function() {
        throttleFn.cancel()
       }
    </script>

debounce

 <script>
        function yydebounce(fn,delay,immediate = true) {
            let timer = null
            let isInvoke = false
            const _debounce = function(...args) {
            return new Promise((resolve,reject) => {
                try {
                    let res = undefine
                    if(timer) clearTimeout(timer)
                    timer = setTimeout(()=>{
                        res = fn.apply(this,args) //类似于发送验证码获取异步请求
                        // if(resultCallback) resultCallback(res)
                        resolve(res) 
                        timer = null
                        isInvoke = false
                    },delay) 
                    if(immediate && !isInvoke){
                        res = fn.apply(this,args)
                        // if(resultCallback) resultCallback(res)
                        resolve(res)
                        isInvoke = true
                        return
                    }
                   
                } catch (error) {
                    reject(error)
                }
               })
               //给函数绑定一个取消函数,成为他的类方法
               _debounce.cancel = function() {
                  if(timer) clearTimeout(timer)
                  timer = null
                  isInvoke = false
               }

            } 
            return _debounce
        }
    </script>