JS中防抖和节流

假设一个场景:比如你快速点击一个按钮的时候,你会发现,无论你点击的有多快,只要点击了一次,日志就会打印一次;

防抖:如果短时间内大量触发同一事件,只会执行一次函数。

需求---在快速点击的过程中,如何只让最后一次点击能产生效果。(使用lodash中的debounce方法实现)

节流:如果短时间内大量触发同一事件,那么函数在执行一次之后,该函数在指定的时间内不在工作,直至过了这段时间才重新生效。

需求---在快速点击的过程中,如何降低一下日志打印的频率,比如1s内最多执行一次。(使用lodash中的throttle方法)

节流和防抖
 节流防抖
场景

1.有些事件是会频繁触发的,比如:keyup(键盘的点击)、scroll(滚动)、resize(屏幕窗口的变化)、mousemove(鼠标的移动)等等。

2.我依然想让它频繁触发事件:只不过不要那么频繁就好

1.有些事件是会频繁触发的,比如:keyup(键盘的点击)、scroll(滚动)、resize(屏幕窗口的变化)、mousemove(鼠标的移动)、搜索框联想建议等等。

2.我不想让它如此频繁触发事件:只需要在最后一次事件做操作即可

实现步骤在产生事件时,判断节流阀,如果节流阀成立,立马将节流阀设置为不成立,然后做正常操作,开启新的定时器,定时器结束时重置节流阀在产生事件时,取消上一次定时器,开启新的定时器
区别

1.一段时间内,可能会产生多次效果,只不过每一次之间的频率降低了

2.在意过程

1.一段时间内,只有最后一次产生效果

2.不在意过程

相同点都是为了降低频率

节流和防抖在Vue项目中的使用

第一步:创建utils.js

utils.js

/**
 *【防抖】
 * 1.设置一个定时器
 * 2.设置一个闭包,返回一个方法
 * 3.如果反复进来,清空前面的定时器
 * 4.再重新设置一遍定时器
 */
export function debounce(fn, delay) {
	let timer = null; //1.设置一个定时器
	return function() { //2.设置一个闭包,返回一个方法
		let _that = this; //保存执行上下文的this
		let args = arguments; //保存传入的参数
		if (timer) {
			clearTimeout(timer); //3.每次事件触发时,都去清除之前的旧定时器
		}
		//4.设立新定时器
		timer = setTimeout(() => {
			fn.apply(_that, args);
		}, delay)
	}
}
/**
 * 【节流】
 * 思路:每次点击的时候,用现在的时间和上一次点击的时间作比较,
 * 如果大于传入的时间,则执行传入的代码,否则不执行。
 * fn:需要节流的回调函数
 * delay:毫秒,计时器,节流期限值,传入的时间,多少时间后执行
 */
export function throttle(fn, delay) {
	let last = 0; //记录上一次执行回调函数的时间
	return function() {
		let _that = this;
		let args = arguments;
		let now = +new Date(); //加'+'表示转化为时间戳
		if ((now - last) >  delay) {
			last = now; //保存该次执行的时间
			fn.apply(_that, args);
		}
	}
	//开启阀门:这种写法也可以
	// let flag = true;
	// return function (){
	// 	let _that = this;
	// 	let args = arguments;
	// 	if(flag){
	// 		flag = false;			
	// 		setTimeout(() => {
	// 			flag = true;
	// 			fn.apply(_that, args);
	// 		},delay)
	// 	}
	// }
}
/**
 *【防抖+节流】
 * 防抖有时候因为触发太过频繁,导致一次响应都没有,
 * 所以希望固定的时间必定给用户一个响应,于是就有了防抖+节流的操作。
 * 1.设置last记录定时器开始的时间
 * 2.设置timer表示一个定时器
 * 3.获取当前时间now
 * 4.如果当前时间 - 开始时间小于延迟时间,那么就防抖
 * 5。否则设置时间到了,执行函数
 */
export function debounceThrottle(fn, delay) {
	let last = 0;
	let timer = null;
	return function() {
		let _that = this;
		let args = arguments;
		let now = +new Date();
		if ((now - last) < delay) {
			clearTimeout(timer);
			timer = setTimeout(() => {
				last = now;
				fn.apply(_that,args);
			},delay)
		}else{
			last = now;
			fn.apply(_that,args);
		}
	}
}

第二步:在Vue组件中引入并使用

<template>
	<div class="home">
		<div @click="handleClick" style="cursor: pointer;">首页</div>
	</div>
</template>

<script>
	import {debounce,throttle} from '../utils/utils.js'//第一种方法:方法引入
	import _ from  'lodash'//第二种方法:使用 lodash 插件
	export default {
		data() {
			return {}
		},
		methods: {
			//第一种方法:方法引入
			handleClick:debounce(function(){
				console.log('防抖');	
			},3000),
			handleClick:throttle(function(){
				console.log('节流');	
			},3000)
			//第二种方法:使用 lodash 插件
			handleClick:_.debounce(function(){
				console.log('lodash:防抖');	
			},3000),
			handleClick:_.throttle(function(){
				console.log('lodash:节流');	
			},3000)
		},
		created() {

		}
	}
</script>

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端报刊

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值