携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
前言
作为一道面试常考题,同时也作为前端常见的一个需求/优化性能的解决方案。防抖和节流在前端这条不归路上一直伴随着我,是时候为这俩爷子出一篇文章了。
这篇文章作为节流和防抖的使用说明书,主要讲解:
- **
防抖**的使用场景 - 手动实现一个防抖函数
- **
节流**的使用场景 - 手动实现一个节流函数
那么,进入正题吧!🤩
**防抖**的使用场景
假设我们在页面上有一个按钮,只要一点击就会触发对应的接口。假设这个接口为保存数据的接口,如果在我们没有做任何操作时,一直点击这个按钮呢?毫无疑问,会连续的多次调用保存接口。然而这种情况不是我们所想要的:
- 是无意义的多次调用接口。
- 是假设调用完接口有返回提示就会很不美观。
那么现在摆在我们眼前的路就是防抖了。
手动实现一个防抖函数
防抖(debounce) :在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
根据以上条件我们可知:
- 需要传入一个回调函数
- 需要使用闭包来保存一个定时器以及限制的时间
GO👇
fucntion debounce(func,time){
let timer = null
return ()=>{
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
func()
}, time)
}
}
**节流**的使用场景
当页面触发drag(拖动)事件或者 scroll(滚动) 时触发某个回调,要设置一个时间间隔。这时候就不能使用防抖了,为什么呢?
防抖是拖拽或者滚动结束之后才返回回调,但是我是需要在过程中进行触发回调,但是又不需要那么的频繁;这时候就使用节流函数,每隔一定的时间进项触发就好了!
手动实现一个节流函数
节流(throttle) :规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
根据以上条件我们可知:
- 需要传入一个回调函数
- 需要使用闭包来保存一个定时器以及限制的时间
GO👇
function throttle(func,time){
let flag = true
return ()=>{
if(flag){
flag = false
func()
setTimeOut(()=>{
flag = true
},time)
}
}
}
方法二:
function throttle(fn, time) {
let prev = new Date().now()
return function () {
let now = new Date.now()
if (now - prev >= time) {
prev = now
fn()
}
}
}
尾声
眨眼一看确实节流函数和防抖函数的实现确实很简单,但有时候理解和手写出来是有些许差异。希望还没掌握的同学,多加练习。