本文已参与「新人创作礼」活动,一起开启掘金创作之路。
节流函数throttle:
就是一定时间内触发一次就将门关起来,等到这一次执行完就将门打开,下一次在进来执行的判断就是门是开着的。所以有一个哨兵标志是否开门关门。
节流函数有两种实现:1.使用时间戳实现 2.使用时间间隔实现
时间戳
第一步:实现简单的根据时间戳控制是否可以执行函数
function throttle(fn, interval) {
//1.记录上一次的开始时间
let startTime = 0
// 2.事件触发时执行的函数
const _throttle = function () {
// 2.1每次触发事件时的当前时间
const nowTime = new Date().getTime()
// console.log(nowTime);
// 2.2使用当前时间减去开始时间与事件间隔相比,达到后则触发一次事件
const remainTime = interval - (nowTime - startTime)
if (remainTime <= 0) {
// 2.3真正的逻辑函数
fn()
// 2.4更新上次时间,用于下一次计算
startTime = nowTime
}
}
return _throttle
}
分析: 此时这种实现的情况。
- 第一次会默认执行,因为一进来的时候nowTime是极大的数字。
- 最后一次即(未达到时间间隔的)是不会执行,当interval=10s时,0-10S持续触发函数 ,到10s的时间间隔这个函数会执行一次,此时stratTime =10 ,当继续持续触发函数的11-20S之间的任何一个时间点停止触发函数则,不会执行函数
升级进行定制
要求:使能控制第一次触发或者不触发(默认为第一次是会触发的)
function throttle(fn, interval, options = { leading: false}) {
+ const { leading} = options
let lastTime = 0
const _throttle = function () {
const nowTime = new Date().getTime()
+ if (lastTime == 0 && leading == false) {
+ lastTime = nowTime
+ }
const remainTime = interval - (nowTime - lastTime)
if (remainTime <= 0) {
console.log( 'remainTime:',remainTime);
fn()
+ lastTime = leading ? nowTime:0
}
}
return _throttle
}
分析: 此时这种实现的情况(+为新增代码)
- 此时当leading为false时,第一次会进行将原本为0的lastTime改为nowTime,则往下进行达不到时间戳要求,要在持续触发达到时间戳时才会触发第一次
- 当执行后的lastTime需要进行处理,若要继续保持不触发下一次新的过程的第一次,则应该将lastTime = 0,以保证下一个新过程可以满足条件进行lastTime=nowTime,阻止下一个过程的第一次运行。若下一个过程的第一次是要运行的则应该经lastTime= nowTime,当下一个过程lastTime是经过一个时间间隔没触发的lastTime,则满足下一个过程的第一次就触发条件的。
接下一节继续封装控制最后一次执行或不执行