前言
面试会被经常问到的知识点,关于防抖(debounce)和节流(throttle),而他们也是我们在做项目是会经常遇到的问题,如果用户点击过多,就会一直不断的给服务器发送请求,就会造成严重的资源浪费,通过防抖和节流可以解决这一问题。
防抖
-
防抖的概念:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则会被重新计时。 为了防止资源的浪费,我们只需要执行最后一次的操作请求。
-
假设有一个需求,用户需要搜索一个东西,我们需要获取去发送请求。
-
代码如下:
let input = document.querySelector('input') let time = null; inp.oninput = function () { if (!time == null) { clearTimeout(time) } time = setTimeout(() => { console.log(this.value); }, 500) }
我们先写一个输入框,定义一个全局变量计时器time,当oninput事件触发的时候就会执行计时器的操作,打印用户输入的值,这时候我们在判断里面写一个清除计时器的操作,就会形成这样的效果,如果在5毫秒内还在输入,就会清除上一次的定时器,然后重新生成一个,到最后就会在500毫秒之后才会引起值的打印,这个时候就完成了防抖的效果。 为了让别人能够更好的看的懂你的代码,我们需要优化一下,就不能在把time设置成全局变量了,需要单独把它写成一个函数。
- 代码如下:
let inp = document.querySelector('input')
inp.oninput = debounce(function () {
console.log(this.value);
}, 500)
function debounce(fn, delay) { //防抖
let time = null
return function () {
if (time !== null) {
clearTimeout(time)
}
time = setTimeout(() => {
fn.call(this)
}, delay)
}
}
优化之后,我们看一下,如果fn直接调用的话,上面的this就会指向全局,所以我们需要用call来改变this的指向之后。完善之后我们看效果:
节流
节流的概念: 规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
-
节流就是控制执行次数 代码如下: 先来个css样式
body { height: 2000px;}
js代码如下:
window.onscroll = throttle(function () {
console.log('hello world');
}, 500)
function throttle(fn, delay) {
let flag = true
//在函数开头判断标志是否为 true
return function () {
if (flag) {
setTimeout(() => {
fn.call(this)
flag = true
}, delay)
flag = false
}
}
}
只要flag为真,计时器就会执行,否则就设置其为false,最后将其函数的执行控制在了500毫秒内,就可以达到节流的效果,控制高频事件执行次数。
节流效果如下:
总结:
防抖就是防止资源浪费,请求过多,导致资源浪费。节流就是在规定时间内执行一定的次数
两种的区别就是:函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。
感谢阅读
参考视频来源于B站晓舟报告
欢迎大家留言讨论