一、防抖(debounce)
某一操作在规定时间内再未触发,则执行回调,若触发,则重新计时。
let start = +new Date();
//声明一个柯里化函数
function debounce(fun, delay){
return function(args){
let that = this;
//执行该语句时若距离上次执行时间未超过delay毫秒,则在定时器执行前清除该
//定时器,并启用新的定时器
//反之超过delay毫秒,定时器ID(fun.id)对应的定时器已执行
clearTimeout(fun.id);
fun.id = setTimeout(function(){ //delay时长后,执行定时器
fun.call(that, args)
},delay)
}
}
let con = function(){
console.log(+new Date - start);
}
let highFun = debounce(con, 1000);
setInterval(highFun, 300); //没有打印
setInterval(highFun, 3000); //第一次4s后打印,之后每隔3s打印
应用场景:
1、用户输入触发请求发送或者窗口更新时,应用debounce减少请求和更新频率。
二、节流(debounce)
规定时间内只触发一次,该时间内的其余触发无效。
let start = +new Date();
let con = function(){
console.log(+new Date - start);
}
function throttle(fn, delay){
let last, stid;
return function(args){
let that = this;
let time = +new Date();
//如果第一次执行或者距离上次执行超过delay,则执行下一次操作
if(!last || time - last > delay){
last = time;
fn.apply(that, args)
}
}
}
//每10ms尝试执行打印操作,实际每约1s执行一次
setInterval(throttle(con, 1000), 10);
应用场景:
1、canvas动画中,结合requestAnimationFrame来控制人物每秒移动的距离
2、发送请求时,在回调成功前阻止请求多次发送
3、窗口的scroll事件中,滑动一定时间或距离后执行自定义操作
三、分时函数
当遇到一次性大量渲染时,尝试将大任务分割成小任务延时完成。
// arr: 源数据
// process: 处理函数
// count: 每次抽取个数
var chunk = function(arr, process, count){
setTimeout(function(){
for(var i = 0, len = Math.min(count, arr.length); i < len; i++) {
//取出数组中的第一个数据进行处理,并在源数据中删除
process(arr.shift());
}
if(arr.length > 0) {
//若有剩余任务,则100ms后调用自身继续处理
setTimeout(arguments.callee, 100);
}
}, 100);
}
应用场景:
1、处理大量DOM渲染时,分割成小任务以减轻浏览器压力。
四、总结:
防抖节流以及分时函数的本质都是限制函数的高频触发来提高页面性能。
参考文章:
https://juejin.im/post/5b8de829f265da43623c4261
https://juejin.im/entry/5815876c8ac247004fb6d132/