一年前端面试记录:节流

正文

最近在面试中遇到过几次手撕节流的情况,于是就研究了一下。
节流的话有三种写法,时间戳, setTimeOut以及综合起来的写法,三种写法各自有自己的特点,下面是三种代码的实现。

时间戳
function myTrottle(fn, delay) { // 开始
	let startTime = 0
	let context = this
	let args = arguments
	return function(){
		let endTime = Date.now()
		if(endTime - startTime > delay) {
			fn.call(context, ...args)
			startTime = endTime
		}
	}
}

时间戳的写法,开始会执行一次,当然,如果startTime初始化为Date.now(),开始的一次就不会执行。

定时器
function myTrottle(fn, delay) { // 开始 + 结束
	let context = this
	let args = arguments
	let timer = null
	return function(){
		if(!timer){
			timer = setTimeout(()=>{
				fn.call(context, ...args)
				timer = null // 这里是赋值 此时setTimeout依然在执行,只不过timer指向为null
			},delay)
		}
	
	}
}

定时器的写法也会立即延迟执行一次,但是由于setTimeout本身的一些问题,延时并不准确,所以有了下面综合的写法。

综合写法

相对于时间戳的写法和定时器的写法,这个最终版综合了时间戳准确的特点,并且也能够像定时器一样执行最后一次。

function myTrottle(fn, delay) { // 开始 + 结束
	let timer = null
	let startTime = Date.now()
	let context = this
	let args = arguments
	return function () {
		let endTime = Date.now()
		let de = delay - (endTime - startTime) 
		clearTimeout(timer) // 这里是clearTimeout,重置定时器
		if(de < 0) {
			startTime = endTime
			fn.call(context, ...args)
		} else{
			timer = setTimeout(()=>{
				fn.call(context, ...args)
			},de)
		}
	}
}

在这段代码中,每次执行时如果时间差值大于delay就会立即执行,并且除了最后一次执行,其他的都是走的时间戳,当停止调用的时候才会走定时器,从而做到最后一次也执行,并且更加准确。

附带一个防抖
function myDebounce(fn, delay) {  // 第一次会执行
	let context = this
	let args = arguments
	let timer = null
	return function(){
		if(timer){
			clearTimeout(timer)
		}
		timer = setTimeout(()=>{
			fn.call(context, ...args)
		},delay)
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值