时间:2021-05-26
在写JS时,这两个函数比较常见,有时候傻傻分不清用哪个,或者说知道代码要怎么写,但要说出它究竟是节流函数还是防抖函数时一脸楞逼。今天有一个同学分享了这两个的区分,我也来回顾一下,加深一下印象,以便日后用到时心里有底。PS:百度和谷歌搜索前几个介绍都是相反介绍,本文为原创,如有雷同纯属抄袭我的。
按照设定的时间固定执行一次函数,比如200ms一次。注意:固定就是你在mousemove过程中,执行这个节流函数,它一定是200ms(你设定的定时器延迟时间)内执行一次。没到200ms,一定会返回,没有执行回调函数的。
主要应用场景有:scroll、touchmove
抖动停止后的时间超过设定的时间时执行一次函数。注意:这里的抖动停止表示你停止了触发这个函数,从这个时间点开始计算,当间隔时间等于你设定时间,才会执行里面的回调函数。如果你一直在触发这个函数并且两次触发间隔小于设定时间,则一定不会到回调函数那一步。
主要应用场景有:input验证、搜索联想、resize
思路: 第一次先设定一个变量true,第二次执行这个函数时,会判断变量是否true,是则返回。当第一次的定时器执行完函数最后会设定变量为flase。那么下次判断变量时则为flase,函数会依次运行。
代码一:首次不执行
function throttle(fn,delay=100){ //首先设定一个变量,在没有执行我们的定时器时为null let timer = null; return function(){ //当我们发现这个定时器存在时,则表示定时器已经在运行中,需要返回 if(timer) return; timer = setTimeout(()=>{ fn.apply(this,arguments); timer = null; },delay); }}代码二:首次执行
function throttle2(fn,delay=100){ let last = 0; return function(){ let curr = +new Date(); if(curr - last > delay){ fn.apply(this,arguments); last = curr; } }}思路:首次运行时把定时器赋值给一个变量,第二次执行时,如果间隔没超过定时器设定的时间则会清除掉定时器,重新设定定时器,依次反复,当我们停止下来时,没有执行清除定时器,超过一定时间后触发回调函数。
代码一:首次不执行
function debounce(fn,delay=200){ let timer = null; return function(){ if(timer) clearTimeout(timer); timer = setTimeout(()=>{ fn.apply(this,arguments); timer = null; },delay); }}代码二:首次执行
function debounce2(fn, delay = 200, atBegin = true) { let timer = null, last = 0,during; return function () { let self = this, args = arguments; var exec = function () { fn.apply(self, args); } if (atBegin && !timer) { exec(); atBegin = false; } else { during = Date.now() - last; if (during > delay) { exec(); } else { if (timer) clearTimeout(timer); timer = setTimeout(function () { exec(); }, delay); } } last = Date.now(); }}上面的代码只是我自己的一个简单实现,看看lodash里面的两个核心实现代码。生产中建议使用它们的库,毕竟有这么多人在用,出bug的机会比较少,我上面的代码有可能有一些情况没考虑到。如果你发现有问题的,也请告诉我。
如果在项目中有需要用到的,可以直接安装单个的NPM模块。throttle和debounce
lodash库里面这两个函数设置的参数有点复杂,记录一下里面的参数和代码使用。
节流(throttle)
官方文档解释:
创建一个节流函数,在 wait 秒内最多执行 func 一次的函数。 该函数提供一个 cancel 方法取消延迟的函数调用以及 flush 方法立即调用。 可以提供一个 options 对象决定如何调用 func 方法, options.leading 与|或 options.trailing 决定 wait 前后如何触发。 func 会传入最后一次传入的参数给这个函数。 随后调用的函数返回是最后一次 func 调用的结果。
注意: 如果 leading 和 trailing 都设定为 true 则 func 允许 trailing 方式调用的条件为: 在 wait 期间多次调用。
如果 wait 为 0 并且 leading 为 false, func调用将被推迟到下一个点,类似setTimeout为0的超时。
参数
func (Function)要节流的函数[wait=0] (number)需要节流的毫秒[options] (Object)选项对象[options.leading=true] (boolean)指定调用在节流开始前[options.trailing=true] (boolean)指定调用在节流结束后返回值 (Function)
返回节流的函数
示例
// 避免在滚动时过分的更新定位jQuery(window).on('scroll', _.throttle(updatePosition, 100));// 点击后就调用 `renewToken`,但5分钟内超过1次。var throttled = _.throttle(renewToken, 300000, { 'trailing': false });jQuery(element).on('click', throttled);// 取消一个 trailing 的节流调用jQuery(window).on('popstate', throttled.cancel);防抖(debounce)
创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 func 方法。 debounced(防抖动)函数提供一个 cancel 方法取消延迟的函数调用以及 flush 方法立即调用。 可以提供一个 options(选项) 对象决定如何调用 func 方法,options.leading 与 options.trailing 决定延迟前后如何触发(先调用后等待 还是 先等待后调用)。 func 调用时会传入最后一次提供给 debounced(防抖动)函数 的参数。 后续调用的 debounced(防抖动)函数返回是最后一次 func 调用的结果。
注意: 如果 leading 和 trailing 选项为 true, 则 func 允许 trailing 方式调用的条件为: 在 wait 期间多次调用防抖方法。
如果 wait 为 0 并且 leading 为 false, func调用将被推迟到下一个点,类似setTimeout为0的超时。
参数
func (Function)要防抖动的函数[wait=0] (number)需要延迟的毫秒数[options] (Object)选项对象[options.leading=false] (boolean)指定调用在延迟开始前[options.maxWait] (number)设置 func 允许被延迟的最大值[options.trailing=true] (boolean)指定调用在延迟结束后返回值 (Function)
返回具有防抖动功能的函数
示例
// 避免窗口在变动时出现昂贵的计算开销。jQuery(window).on('resize', _.debounce(calculateLayout, 150));// 当点击时 `sendMail` 随后就被调用。jQuery(element).on('click', _.debounce(sendMail, 300, { 'leading': true, 'trailing': false}));// 确保 `batchLog` 调用1次之后,1秒内会被触发。var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });var source = new EventSource('/stream');jQuery(source).on('message', debounced);// 取消一个 trailing 的防抖动调用jQuery(window).on('popstate', debounced.cancel);以上就是这篇节流和防抖的全部介绍,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
函数防抖和节流都是对高频动作触发回调函数的一个优化,实现方式上有类似之处。先从使用场景做个区分。防抖使用场景:表单输入框校验提交按钮避免重复提交节流使用场景:s
面试的时候我们经常会问别人是理解什么是节流和防抖,严格的可能要求你写出节流和防抖函数,这里我们抛开loadsh工具库手写节流和防抖1.节流函数throttle/
分时函数和函数节流的问题不一样,函数节流针对的事件不是用户主动调用的,前面已经提过了。函数节流的原理是:延迟当前函数的执行,如果该次延迟还没有完成,那么忽略接下
本文实例讲述了js防抖函数和节流函数使用场景和实现区别。分享给大家供大家参考,具体如下:开发过程中,都遇到过某个事件被频发触发的场景,比如resize,scro
防抖和节流的区别是防抖即触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。节流即高频事件触发,但在n秒内只会执行一次,所以节流