函数的防抖和节流

场景:事件频繁被触发,频繁执行DOM操作、资源加载等重复行为,导致UI停顿甚至浏览器崩溃。如 input 实时搜索、scrollview 滚动更新。

函数防抖和节流用于限制函数的执行。是优化高频率执行js代码的一种手段。


函数防抖

函数防抖就是让某个函数在上一次执行后,满足等待某个时间内不再触发此函数后再执行,而在这个等待时间内再次触发此函数,等待时间会重新计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
var debounce = function(idle,action){
var last;
return function(){
var ctx = this,
args = arguments; // 存储参数
clearTimeout(last);
last = setTimeout(function(){
action.apply(ctx,args);
},idle);
}
}

// 返回函数连续调用时,空闲时间必须大于或等于idle,action才会执行。

实际例子

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下图,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function debounce(fn, wait) {
var timeout = null;
return function() {
if(timeout !== null)
clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

当持续触发scroll事件时,事件处理函数handle只在停止滚动1000毫秒之后才会调用一次,也就是说在持续触发scroll事件的过程中,事件处理函数handle一直没有执行。

函数防抖适用于连续调用函数,但只在延时后调用一次。定时器存在则销毁,第一次一定会创建并调用函数。

函数节流

每隔某个时间去执行某函数,避免函数的过多执行。

如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。也就是说会先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

1
2
3
4
5
6
7
8
9
10
var throttle = function(delay,action){
var last ;
return function(){
var cur = +new Date(); //返回毫秒数
if(cur - last > = delay){
action.apply(this,arguments);
last = cur;
}
}
}

实际例子

函数节流主要有两种实现方法:时间戳和定时器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var throttle = function(func, delay) {
var prev = Date.now();
return function() {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
prev = Date.now();
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var throttle = function(func, delay) {
var timer = null;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function() {
func.apply(context, args);
timer = null;
}, delay);
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));

函数节流适用于间接性调用函数。定时器不存在则创建调用函数,定时销毁。

本文结束感谢您的阅读

本文标题:函数的防抖和节流

文章作者:陈宇(cosyer)

发布时间:2018年07月03日 - 22:07

最后更新:2020年03月15日 - 00:03

原始链接:http://mydearest.cn/%E5%87%BD%E6%95%B0%E9%98%B2%E6%8A%96%E5%92%8C%E8%8A%82%E6%B5%81.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!