实用技能一:防抖与节流

防抖与节流

1. 用途

防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。

举例来说,一个点击事件会发起一次请求,用户拼命去快速点击,就会发起许多次请求,这显然不合理,防抖节流就是限制这种行为。

注意:防抖是控制次数,节流是控制频率

2. 防抖(debounce)

防抖是无论触发多少次事件,只执行最后一次;

具体来说就是:规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间

案例:

点击.box元素,1s后输出123;在点击了之后,1s内再点多少次,都以最后一次点击为准重新开始出现计时1s,然后输出一次123

function debounce(fn,waitTime){
    let timeout =null
     return function(){
         if(timeout!==null){
             clearTimeout(timeout)
         }
         timeout=setTimeout(fn,waitTime)
     }
 }
function cs(){
   console.log(123)
}
document.querySelector(".box").addEventListener("click",debounce(cs,1000))

3. 节流(throttle)

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。通俗来说就是假如规定点击之后1s内发起一次请求,这1s内无论点多少次,无论请求有没有完成,都不会再发起请求

对于节流,一般有两种方式可以实现,分别是时间戳版和定时器版。

1) 时间戳版:
function throttle(fn,waitTime){
     let prev=Date.now()
     return function(){
         let now=Date.now()
         if(now - prev > waitTime){
             fn()
             prev=Date.now()
         }
     }
 }
function cs(){
    console.log(123)
}
document.querySelector(".box").addEventListener("click",throttle(cs,1000))

每次执行fn函数都会更新prev用来记录本次执行的时间,下一次事件触发时判断时间间隔是否到达预先的设定,重复上述操作。

2) 定时器版:
function throttle(fn,waitTime){
    let timeout=null
    return function(){
        if(!timeout){
            fn()  //放在这可以先执行,不用等1s
            timeout=setTimeout(function(){
            	//fn() 放这里是1s后执行
                timeout=null;
            },1000)
        }
    }
}
function cs(){
        console.log(123)
 }
document.querySelector(".box").addEventListener("click",throttle(cs,1000))

4. vue项目中遇到的案例

1) 需求:点击一个div元素,发起请求,获取到数据,之后弹出弹窗,渲染弹窗
2)问题:如果不进行防抖节流,一直点击div元素,就会一直发起请求;如果使用定时器的方法来实现防抖节流,无法掌握请求响应时间与设置的时间之间的长短问题,长了用户觉得反应慢,短了又会发起请求
3)解决:

  • 在data中设置一个变量status=true
  • 开始执行函数就将变量重新赋值为false,接着执行请求函数,此时再触发点击事件,也不能满足条件发起请求函数
  • 请求函数使用async和await,在发起请求,处理完数据之后,再将status重新赋值为true,这样点击事件又能执行请求函数
  • 这样点击之后,弹窗没出来之前,只能触发一次请求函数,直到请求函数执行完毕,才能再次触发,时间刚刚接上,比定时器要灵活
//请求函数
async fn(){
	//发起请求
	let data=await axios(xxxxxx)
	//处理数据
	xxxxxx
	//将变量status=true
	this.status=true
}
//点击函数
clickEvent(){
	//第一次是true,执行请求函数
	if(this.status){
		//一开始执行就将变量status=false
        this.status=false
        //执行请求函数
        this.fn()
     }
}

你可能感兴趣的:(前端常用方法,防抖与节流)