点击按钮打开一个页面,但是按钮点击一次页面打开两次,如何处理?
我们肯定会想到节流与防抖函数,这两个函数很像,到底有什么区别呢?
如果这么写:
onClick = _.throttle(()=>{
openNextPage();
}, 3000);
或者
onClick = _.debounce(()=>{
openNextPage();
}, 3000);
一个按钮快速点击10次,上面两种写法会发生什么? 会存在哪些问题?
防抖 debounce
第一次点击开始计时,中间有重复触发,则倒计时重置,倒计时结束后触发
适用不想重复的场景,某段时间内只执行一次: 比如点击
节流 throttle
第一次点击触发,设定时间内的重复触发都被抛弃
比如:按钮点击、resize window
适用想重复(每隔N秒)但是不想太频繁的场景,固定频率:
比如:用户输入的验证、scroll触发、resize window
手写防抖
functuon debounce(fn, wait){
let timer = null;
return function(){
let context = this;
let args = arguments;
// 重复触发则重置
if(timer){
clearTimeout(timer);
timer = null;
}
// 设置定时器
timer = setTimeout(()=>{
fn.apply(context, args);
}, wait);
}
}
手写节流
function throttle(fn, time){
let curTime = Date.now();
return function(){
let context = this;
let args = arguments;
let nowTime = Date.now();
if(nowTime - curTime >= time){
curTime = Date.now();
return fn.apply(context, args);
}
}
}
场景1:
onClick = _.throttle(()=>{
openNextPage();
}, 3000);
Q: 一个按钮快速点击10次,会发生什么? 会存在哪些问题?
A: 立即执行,然后3s后再执行一次
场景2:
onClick = _.debounce(()=>{
openNextPage();
}, 3000);
Q: 一个按钮快速点击10次,会发生什么? 会存在哪些问题?
A: 每次点击都会重新计时,计时结束后才会执行打开下一页的操作,所以打开下一页的时间是大于3s的(最后一次点击开始计时)
场景3:
onClick = _.debounce(()=>{
openNextPage();
},
3000,
{leading: true, tailing: false});
Q: 一个按钮快速点击10次,会发生什么? 会存在哪些问题?
A: 立即执行一次,后面的点击到导致不断重复计时,只有最后一次点击3秒后才能执行
点击防抖到底应该怎么做
如果是未知原因的点击一次,响应两次,可以设置wait为500ms
onClick = _.debounce(()=>{
openNextPage();
}, 500);
如果是防止快速点击,设置1s即可,但是要加leading:true,保证先执行
onClick = _.debounce(()=>{
openNextPage();
},
1000,
{leading: true, tailing: false}
);