函数防抖和节流

函数防抖和节流是用来干什么的?
  • 是优化高频率执行js代码一种手段。
  • 在js中有一些事件在触发时会不断调用绑定在事件上的回掉函数,极大地浪费资源,降低性能。
  • 上述事件有resize、scroll、mousemove、mouseover、input输入框的keypress事件等
  • 所以为了优化体验,需要对这类事件进行调用次数的限制。
1. 防抖

定义:
指触发事件后在n秒内函数只执行一次,如果在n秒内又触发事件,则会重新计算函数执行时间
(计时清零)

防抖分为非立即执行版和立即执行版。

  • 所谓非立即执行就是触发事件后,函数不会立即执行,而是在n秒后执行,如果在n秒内又触发了事件,则会重新计算函数执行时间(即延迟执行)

代码如下:

function debounce(func, wait){
	let timer;
	return function(){
		let _this = this;
		let args = arguments;
		if(timer) {
			clearTimeout(timer);
		}
		timer = setTimeout(() => {
			func.apply(_this, args);
		}, wait)
	}
}
  • 立即执行就是触发事件后函数会立即执行,执行后的n(s)内忽略后续触发

代码如下:

function debounce(func,wait){
	let timer;
	return function(){
		let _this = this;
		let args = arguments;
		if(timer){
			clearTimeout(timer);
		}
		let callNow = !timer;
		timer = setTimeout(() => {
			timer = null;
		}, wait)
		if(callNow){
			func.apply(_this,args);
		}
	}
}
  • 在开发的过程中我们需要根据不同的场景来决定使用哪种防抖函数。结合版代码如下
// immediate 表示是否立即执行
function debounce(func,wait,immediate){
	let timer;
	return function(){
		let _this = this;
		let args = arguments;
		if(timer) {
			clearTimeout(timer);
		}
		if(immediate) {
			let callNow = !timer;
			timer = setTimeout(() => {
				timer = null;
			}, wait);
			if(callNow){
				func.apply(_this,args);
			}
		} else {
			timer = setTimeout(() => {
				func.apply(_this, args);
			}, wait)
		}
	}
}
2. 节流(throttle)

定义:
节流是指连续触发事件在n秒中只执行一次。

节流的两种实现方式:

  • 时间戳版(立即执行)
  • 函数是在时间段开始时候执行
    代码如下:
function throttle(func,wait){
	let previous = 0;    // 执行代码时的时间
	return function(){
		let now = Date.now();   //  触发事件时的时间
		let _this = this;
		let args = arguments;
		if(now - previous > wiat) {
			func.apply(_this,args);
			previous = now;
		}
	}
}
  • 定时器版(非立即执行)
  • 函数是在时间段结束后执行
    代码如下:
function throttle(func,wait){
	let timer;
	return function(){
		let _this = this;
		let args = arguments;
		if(!timer){
			timer = setTiment(() => {
				timer = null;
				func.apply(_this, args)
			}, wait)
		}
	}
}

依然结合两种方式整合函数节流,代码如下:

// type=1时间戳版 type=2定时器版
function throttle(func,wait,type){
	if(type === 1){
		var previous = 0;    //  注意:这儿使用var而不使用let的原因是let会形成块级作用域,外面访问不到
	} else if(type === 2) {
		var timer;
	}
	return function(){
		let _this = this;
		let args = arguments;
		if(type === 1){
			let now = Date.now();
			if(now - previous > wait) {
				func.apply(_this,args);
				previous = now;
			}
		}else if(type === 2) {
			if(!timer) {
				timer = setTimeout(() => {
					timer = null;
					func.apply(_this,args);
				},wait)
			}
		}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值