防抖:用户触发事件过于频繁,只要最后一次事件的操作
节流:控制执行次数,控制高频事件执行次数
防抖的情况:
比如我们输入框输入时请求后台数据,但我们希望输完之后请求,防止请求后台接口次数过多。
那么我们可以利用计时器来实现防抖和节流:
以下前端演示防抖的情况,不涉及后端。如下代码,我们可以在浏览器查看打印结果,可以看到每当我们在input框输一次,控制台就跟着打印一次,那么我们可以想象如果我们请求的是后端接口,那么每次输入就请求会耗费很大的性能。
<body>
<input type="text"/>
<script>
let inp=document.querySelector("input")
inp.oninput=function(){
console.log(this.value)
}
</script>
</body>
那么我们如何做个防抖事件呢:我们写个计时器
<body>
<input type="text"/>
<script>
let inp=document.querySelector("input")
let t=null;
inp.oninput=function(){
if(t!==null){
//将上一次的定时器先删除(执行很多次的,就比如
//连续的输个1出1,输2出2,输3出3,
//我们防抖主要就是要最后的结果123,所以把那三次计时器都删除掉)
clearTimeout(t)
}
//然后开始新的定时器(刚进来的时候先走下面代码,
// 因为刚开始null为空)
t=setTimeout(()=>{
console.log(this.value)
},500)
}
</script>
以上代码可以做到减少我们的性能消耗,但是对我们后续维护我们代码的同学可能看这串代码有点不易理解,所以我们将防抖进行一个封装
<body>
<input type="text"/>
<script>
let inp=document.querySelector("input")
inp.oninput=debounce(function(){
// 业务代码
console.log(this.value)
},500)
function debounce(fn,delay){
let t=null;
return function(){
if(t!==null){
clearTimeout(t)
}
t=setTimeout(()=>{
//可以改变我们上方业务代码中this指向为input,否则指向为window
fn.call(this)
t = null;
},delay)
}
}
</script>
</body>
那么防抖我们就大功告成了,接下来我们来理解一下节流,节流在什么情况下使用呢,就比如resize(屏幕大小改变),onmounceover等事件都会用到节流,我们讲解滚动滚动条情况使用节流,如下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body{
height: 2000px;
}
</style>
</head>
<body>
<script>
window.onscroll=function(){
console.log("123")
}
</script>
</body>
</html>
我们每次滚动滚动条的时候都会输出,那么我们想象如果是请求数据的,那么是不是很耗费性能,那么怎么控制这个次数呢,见以下代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body{
height: 2000px;
}
</style>
</head>
<body>
<script>
let flag=true
window.onscroll=function(){
debugger
if(flag==true){
setTimeout(()=>{
console.log("123")
//把执行控制在了每五秒执行一次,
//如果不加flag=true,它就执行一遍再也不执行了
flag=true
},5000)
}
flag=false
}
</script>
</body>
</html>
那么我们也对上面方法进行一个封装
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body{
height: 2000px;
}
</style>
</head>
<body>
<script>
window.onscroll=trottle(function(){
console.log("123")
},5000)
function trottle(fn,delay){
let flag=true
return function(){
if(flag==true){
setTimeout(()=>{
fn.call(this)
flag=true
},delay)
}
flag=false
}
}
</script>
</body>
</html>
好啦,节流也大功告成!
如果有小伙伴想用vue+axios封装防抖和节流,请参考Vue + Axios全局接口防抖、节流封装实现,让你前端开发更高效 - 掘金