本文已参与「新人创作礼」活动,一起开启掘金创作之路。
接上节0.1
继续订制
要求实现,最后一次的调用与不调用控制
function throttle(fn, interval, options = { leading: true, trailing: false }) {
const { leading, trailing } = options
let lastTime = 0
+ let t = null
const _throttle = function () {
const nowTime = new Date().getTime()
if (!lastTime && !leading) lastTime = nowTime
const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
+ if (t) {
+ clearTimeout(t)
+ t = null
+ }
fn()
lasttTime = leading ? new Date().getTime(): 0
return
}
+ if (trailing && !t) {
+ t = setTimeout(() => {
+ t = null
+ lastTime = leading ? new Date().getTime(): 0
+ fn()
+ }, remainTime)
+ }
}
return _throttle
}
分析:
- 1.当不满足时间戳时开启定时器,若到时间戳,则清除定时器,走上面满足时间戳的过程,且若执行完时间戳部分就应该return,不要向下执行,又多增计时器
- 2.若没有达到时间戳,就代表这个过程的最后一次触发是交给了定时器,则定时器需要将t置为null,为下一个过程能开启计时器,lastTime的处理同上次的逻辑。这里是存在转移的, 因为在人为控制的触发是很难次次达到刚好满足事件戳,即remianTime刚好=0的大多都是remainTime为负数,即很难做到按理想情况清楚定时器,所以,此时将lastTime置为nowTime的执行时间,则就阻止了原本满足remain<=0的条件,所以变成了每次执行计时器,计时器将原本的时间戳函数阻止,其实效果是一样的,因为在哪个时间点只要执行一次就好,而很难清除定时器,所以就阻止原本的时间戳函数。当leading为false时,lastTime=0,则又会在第一次是否执行哪里进行判断,又会阻止时间戳函数的执行,所以在这个时间点,无论计时器将lastTime如何处理都有对应逻辑阻止时间戳函数的执行。
上面的大抵不好懂
基本的计时器实现
function throttle(fn, delay) {
let flag = true
function _throttle() {
if (flag == false) {
return
}
flag = false
setTimeout(() => {
fn()
flag = true
}, delay)
}
}
这种很容易就是一旦执行就关门,等到函数执行完了,函数会讲门打开,下一次判断就能触发新的依次函数执行