防抖与节流函数

防抖(Debounce)

概念

防抖,指的是在触发事件后的一定时间内(例如 3秒)函数只能执行一次,如果在这段时间(3秒)内再次触发事件,则会重新计算函数执行的时间。
为了更好的理解,在这边举个公交车的例子:公交车上,只要乘客不断地刷卡,司机师傅就不能开,等乘客都上车了,再等待的时间内没有人上车,才会开车走。如果在wait的时间内又有人上车,那就重新开始一个等待时间

防抖函数分类
  • 非立即执行
  • 立即执行
非立即执行版

就是在触发事件后不立即执行,而是在一定的等待时间后执行如果在这段时间内又触发事件,就重新计算执行时间。

/**
* @fn : 要执行的函数
* @delay : 执行执行函数的时间间隔
*/
// 输入完毕等待2秒后再可以查询(延迟执行)
function debounce (fn, delay=2000) {
	let timer; // 定时器
	return function (...args) {
		let _this = this; // 绑定函数执行时的this绑定
		timer && clearTimeout(timer); // 当函数再次执行的时候,清楚定时器,让定时器重新开始计时
		timer = setTimeout (() => {
			// 执行传入的函数
			fn.apply (_this, args); // args是执行函数传入进来的参数
		}, delay)
	}
}
立即执行版
// 输入完毕后立即查询,过2秒后才能再查询(立即执行)
function debounce (fn, delay=2000) {
	let timer;
	return function (...args) {
		let _this = this
		timer && clearTimeout(timer);
		let callNow = !timer;
		timer = setTimeout (() => {
			timer = null;
		}, delay);
		if (callNow) {
			fn.apply(_this, args)
		}
	}
}
例子:
<input type="text" id="text">
let ipt = document.getElementById('text')
ipt.addEventListener('input', function(){
	let val = this.value
	handle(val)
})
let handle = debounce(handleSendPhone,2000);
// handleSendPhone就是要等待执行的函数
function handleSendPhone (val) {
	ajaxRequest({
		user: val
	}).then((res)=>{
		console.log(res)
	})
}


// 模拟请求的数据
let datas = ['aaa','bbb','ccc','ddd']
  function ajaxRequest({
    user
  }) {
    return new Promise((resolve, reject) => {
      let res = datas.includes(user) ? '正确' : '失败'
      resolve(res)
    })
  }
两种都兼容的写法
/**
* @fn : 要执行的函数
* @delay : 执行执行函数的时间间隔
* @immediate: true 立即执行 false 非立即执行
*/
function debounce (fn, delay, immediate=false) {
	let timer;
	return function (...args) {
		let _this = this
		timer && clearTimeout(timer)
		if (immediate) {
			let callNow = !timer
			if (callNow) {
				fn.apply(_this,args)
			}
			timer = setTimeout(() => {
				timer = null
			},delay)
		} else {
		// timer 一定要赋值
			timer = setTimerout(() => {
				fn.apply(_this,args)
			},delay)
		}
	}
}

节流(throttle)

概念

节流,指的是某个函数在一定时间间隔内(例如3秒)只执行一次,在这3秒内又调用请求会无视,也不会延长时间间隔。

例子
/**
* @fn : 要执行的函数
* @delay : 时间间隔
* @ return : 节流函数
*/
function throttle (fn, delay) {
	let timer;
	let prevTime; // 记录上一次执行的时间
	return function (...args) {
		let _this = this
		let currTime = Date.now(); // 获取当前时间戳
		`也可以这样获取 let currtime = +new Date()`
		if (!prevTime) {
			prevTime = currTime;
		} // 第一次执行时,prevTime赋值为当前时间
		timer && clearTimeout(timer); // 每次都清除定时器,保证定时器只是在最后一次执行
		if (currTime - preTime > delay) { // 如果为true,则表示两次执行函数的时间间隔为delay.
			prevTime = currTime; // 重置上次记录的时间
			fn.apply(_this, args); // 执行函数,发送请求
		} else {
			timer = setTimeout(() => {
				prevTime = Date.now(); 
				fn.apply(_this, args); 
			}, delay)
		}
	}
}

总结

  • 防抖和节流在一定程度上相似,都是为了节省资源,提升用户的体验。
  • 防抖是在函数触发后延迟执行,在延迟时间内再次触发,会重新计算执行时间
  • 节流是在函数连续点击时,在规定的时间内只执行一次。

最后

如果文章中有错误,请务必指出,万分感谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值