javascript - 关于函数节流,定时器里的fn.applay()感觉好诡异?
本文介绍了javascript - 关于函数节流,定时器里的fn.applay()感觉好诡异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
代码不复杂,逻辑很简单,就是函数节流,我直接放代码了。
var count = 0
setInterval(() => console.log(new Date().getSeconds()),1000)
function doSomthing() {
console.log('懵逼。。。。')
count ++;
}
window.onresize = throttle(doSomthing,1000)
function throttle(fn, threshhold) {
// 记录上次执行的时间
var last
// 定时器
var timer
// 默认间隔为 250ms
threshhold || (threshhold = 250)
// 返回的函数,每过 threshhold 毫秒就执行一次 fn 函数
return function () {
// 保存函数调用时的上下文和参数,传递给 fn
var context = this
var args = arguments
var now = +new Date()
// 如果距离上次执行 fn 函数的时间小于 threshhold,那么就放弃
// 执行 fn,并重新计时
if (last && now < last + threshhold) {
clearTimeout(timer)
// 保证在当前时间区间结束后,再执行一次 fn
timer = setTimeout(function () {
last = now
console.log('第'+count+'次执行')
fn.apply(context, args)
}, threshhold)
// 在时间区间的最开始和到达指定间隔的时候执行一次 fn
} else {
last = now
fn.apply(context, args)
}
}
}
理论上当我不断改变浏览器窗口大小的时候(就是说间隔肯定小于1s的),doSomthing
从第二次开始是不会被执行的。因为我在不断的执行 cleraTimeout
,实际运行结果是 console.log('第'+count+'次执行)
确实没有被打印出来,但是当我停止改变浏览器窗口的时候,发现打印出来的 count
并不是 1
,而且是一个很大的数。
这说明,在这段代码里:
timer = setTimeout(function () {
last = now
console.log('第'+count+'次执行')
fn.apply(context, args)
}, threshhold)`
setTimeout()
里的匿名函数没有被执行,但是匿名函数里的 fn.apply()
却被执行了,求大神告知原理何在啊?还是我这段代码本身有问题?
解决方案
除了setTimeout
里的之外,在
if (last && now < last + threshhold) { \*...*\ }
else {
last = now
fn.apply(context, args) //这里还有一个fn.apply()
}
在改变浏览器大小时,else里的这个fn.apply
会每隔threshhold毫秒执行一次
所以setTimeout
确实只执行了一次,其余的次数是else里的fn.apply
执行的
这篇关于javascript - 关于函数节流,定时器里的fn.applay()感觉好诡异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文