防抖和节流

最近在面试的时候有一面试题是关于防抖节流的,回来加强了一下,做以下总结,希望对大家有所帮助!

先来说一下防抖和节流的应用场景

  防抖 - debounce:

         1、input框输入时,可以使用防抖节约资源的请求,比如搜索框

    2、window触发resize时,当用户停止改变窗口的大小时,再触发事件

   节流 - throttle:

   1、 scroll滚动事件

   2、鼠标不断点击,mouseover事件等

 总结:

  防抖: 当触发间隔大于设定时间,执行业务方法,分为两种,立即执行防抖,非立即执行防抖

        // 非立即执行防抖
          function debounce(fun,wait) {  //当定时器还在计时的时候触发,就会清除定时器并开始新的定时器,这样回调函数又得等待wait毫秒,如果一直不断触发就会一直不执行回调
            let timeout
            return function() {
                let content = this
                let args = arguments
                if(timeout) clearTimeout(timeout)
                timeout = setTimeout(function(){
                    fun.apply(content,args)
                },wait)
            }
          }
 
      //立即执行防抖
         function debounce(fun,wait) {  //定时结束请空定时器,根据定时器是否为空来判定是否执行回调
            let timeout
            return function() {
                let content = this
                let args = arguments
                if(timeout) clearTimeout(timeout)
                let callNow = !timeout
                timeout = setTimeout(function(){
                    timeout = null
                },wait)
                if(callNow) fun.apply(content,args)
            }
         }
 
     // 封装防抖函数,根据自己的需求设置,immediate判断是否立即执行
         function debounce(fun,wait,immediate) {
            let timeout
            return function() {
                let content = this
                let args = arguments
                if(timeout) clearTimeout(timeout)
                if(immediate) {
                    let callNow = !timeout
                    timeout = setTimeout(function(){
                        timeout = null
                    },wait)
                    if(callNow) fun.apply(content,args)
                } else {
                    timeout = setTimeout(function(){
                        fun.apply(content,args)
                    },wait)
                }
            }
        }
    
       //节流,连续触发事件,每隔一定时间,执行一次业务方法
       //第一种,定时器方式,第一次触发需要等待delay
       function throttle(func,delay) {
            var timer = null
            return function() {
                let that= this
                let args = arguments
                // 定时器不存在时,触发一个定时器,回调中清除定时器
                if(!timer) {
                    timer = setTimeout(() => {
                        func.apply(that,args)
                        timer = null
                    }, delay);
                }
            }
        } 
     //第二种,时间戳方式,第一次触发无需等待
    function throttle(func,delay) {
      let previous = 0
      return function() {
        let now = new Date()
        let that = this
        let args = arguments
        if(now - previous > delay) {
          func.apply(that,args)
          previous = now
        }
      }
       }

   //封装,type为1时使用时间戳,type为2时使用定时器
    function throttle(fun,delay,type) {
            if(type == 1) {
                var previous = 0
            }else if(type == 2){
                var timeout
            }
            return function() {
                let content = this
                let args = arguments
                if(type == 1) {
                    let now = new Date()
                    if(now-previous > delay) {
                        fun.apply(content,args)
                        previous = now
                    }
                }else if(type == 2) {
                    if(!timeout) {
                    timeout = setTimeout(function(){
                        timeout = null
                        fun.apply(content,args)
                    },delay)
                }
                }
            }
        }
原文地址:https://www.cnblogs.com/linhongjie/p/11980246.html