// 节流是值函数在连续触发的情况下,在规定的时间内,无论如何都会执行一次,比如设置的延迟时间为250 // 那么如果连续点击1秒钟,那么会执行4四次,而且四次的时间间隔250 /** * @description 节流函数(首节流,第一次触发会立即执行) * @param { Function } - 要添加节流功能的函数 * @param { number } - 要延迟的毫秒数 */ export function firstThrottle(fun, delay) { var flag = true // 是否可以执行 return function(){ if(!flag) return // 不能执行就直接返回 // 获取参数和上下文 var args = arguments var context = this fun.apply(context, args) // 执行完成之后,把flag设置成false表示不能执行,并设置定时器,delay毫秒之后设置true flag = false setTimeout(function(){ flag = true }, delay); } } /** * @description 节流函数(尾节流,无论延迟设置多久,总会执行最后一次) * @param { Function } - 要添加节流功能的函数 * @param { number } - 要延迟的毫秒数 */ export function lastThrottle(fun, delay) { var timer = 0 return function () { if(timer) return var args = arguments var context = this timer = setTimeout(function () { fun.apply(context, args) timer = 0 },delay) } } /** * @description 节流函数(首节流,通过时间戳实现) * @param { Function } - 要添加节流功能的函数 * @param { number } - 要延迟的毫秒数 */ export function lastThrottleByTime(fun, delay) { var pre = 0 return function () { var cur = Date.now() // 获取当前的时间戳 if(cur - pre > delay) { var args = arguments var context = this fun.apply(context, args) pre = cur } } } // 思考:首节流适用delay大且对最终状态无要求的功能,缺点是不会执行最终状态。 // 尾节流适用delay不大且对最终状态有要求的功能,缺点是,当delay大时用户会认为自己的第一次点击好像无效 // 又没有什么办法可以是首节流,又保留最终状态?之前我们讲过防抖,防抖在高频率出发下,只会触发最后一次,这不就是我们要的尾状态吗! /** * @description 节流函数(首尾节流,通过时间戳实现) * @param { Function } - 要添加节流功L的函数 * @param { number } - 要延迟的毫秒数 */ export function firstAndLastThrottle(fun, delay) { var pre = 0 var timer = 0 var _delay = delay + 100 // 防抖用的时间间隔,比节流大0.1秒,因为人对0.1秒的延迟无感知 return function () { var args = arguments var context = this var cur = Date.now() // 获取当前的时间戳 if(cur - pre > delay) { fun.apply(context, args) pre = cur } clearTimeout(timer) timer = setTimeout(() => { fun.apply(context, args) }, _delay); } }