防抖函数节流函数
分类:javascript
防抖和节流主要用于 scroll, mousemove ,resize, 但有些时候,我们并不希望再时间持续触发的国成中,那么频繁的去执行函数,
场景: 输入框持续输入,将输入内容持续校验。防抖是控制次数, 节流是控制频率。
防抖(debounce)
防抖是指触发事件后在 n 秒内函数只执行一次, 如果在 n 秒内又触发了事件, 则会重新计算函数执行时间。
需求描述:
函数防抖, 这里的抖动就是执行的意思, 而一般的抖动都是持续的, 多次的。 假设函数持续多次执行, 我们希望让它冷静下来执行。 也就是当持续触发事件的时候, 函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行,
分解一下需求,
- 持续触发不执行
- 不触发的一段时间执行
function debounce(func, deplay){
let timeout ;
return function(){
clearTimeout(timeout)
timeout = setTimeout(function(){
func.apply(this, arguments)
}, deplay)
}
}
// 用法:
box.onmousemove = debounce(function(e){
box.innerHtml = `${e.clientX}, ${e.clientY}`
}, 1000)
节流 (throttle)
节流, 就是指连续触发事件但是在 n 秒钟只执行一次函数。 节流会稀释函数的执行频率。
对于节流, 一般有两种方式实现, 分别是时间戳版和定时器版
同样分解一下
- 持续触发并不会执行多次
- 到一定时间再去执行
思考:持续触发, 并不会执行, 但是到时间了就会执行。 抓取一个关键的点:就是执行的时机, 要做到控制执行的时间, 我们可以通过一个开发, 与定时器 setTimeout 结合完成。
函数执行的前提条件是开关打开, 持续触发时,持续关闭开关, 等到 setTimeout 到时间了, 再把开关打开 ,函数就会执行了。
时间戳版:
function throttle(func, wait) {
let pervious = 0
return function(){
let now = Date.now();
let context = this;
let args = arguments;
if(now -previous > wait) {
func.apply(context, args);
perviose = npw
}
}
}
定时器版本
function throttle(func, await){
let run = true
return function () {
if(!run) {
return // 如果开关关闭了, 那就直接不执行下边的代码
}
run = false // 持续触发的话, run 一直是false, 就会停在上边的判断哪里
setTimeout(()=>{
func.apply(this,arguments)
run = true //定时器到时间之后,会把开关打开 ,我们的函数就会被执行,
},delay)
}
}
// 调用的时候:
box.onmousemove = throttle(function (e) {
box.innerHtml = `${e.clientX}, ${e.clientY}`
},1000)
总结
防抖和节流巧妙地用了 setTimeout, 来控制函数执行的时间, 优点很明细 ,可以节约性能, 不至于多次触发复杂的业务逻辑而造成页面的卡顿。
引申
call apply bind 的区别
- call
- apply
- bind
一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu