项目中保存调用太频繁,同事做了一个节流,发现做的不是想要的效果,会丢失最后一次要保存的数据。搜索发现网上的节流函数也是一样的。今天好好学习一下什么是节流。
网上的资料大多是千篇一律,写的太烂,前后矛盾,误导新人。
这篇写的还不错:#防抖和节流 #什么是防抖和节流 - jaycethanks - 博客园 (cnblogs.com)
这篇说,“防抖”是为了解决手抖,点按钮连续点好几次的问题。
实现方式是,点击完按钮,不立即执行,而是延迟一定时间之后再执行,如果延迟过程中,又点击了,取消之前的延迟,重新开始延迟任务。
最终结果就是,如果你快速连续点击,点击过程中不会执行,只有在最后一次点击之后,再过一段时间(延迟指定的时间)才会执行。
函数的防抖和节流是个啥??? - 知乎 (zhihu.com)这一篇是拿鼠标移动来举例的,鼠标移动是个很频繁的事件,使用防抖的结果就是,鼠标连续移动过程中不会执行,鼠标停止移动之后,再过一段时间才会执行。
Debouncing and Throttling Explained Through Examples | CSS-Tricks (css-tricks.com)这篇中举了一个电梯的例子,电梯是定时关门的,如果电梯还没关门,有人上来了,电梯又会重新开始倒计时,如果关门之前又有人上来了,电梯又会重新开始倒计时。
看了上面的3个例子,防抖的功能就很清楚了。对于连续调用,防抖是只执行最后一次,而且是延迟执行。
再看节流。
上面第一篇中,拿技能CD来举例,也就是说节流会执行第一次,执行完,会进入技能冷却期,技能冷却期间,再放技能是不起作用的,等技能冷却结束之后再释放技能,才会执行。
上面第二篇对于节流解释的不好。
上面第三篇中,是拿瀑布流(无限下拉页面)来举例,页面滚动到底部,要加载下一页,但是滚动事件太频繁,下一页还没加载出来,又加载下下页,服务器就被搞死了。所以,第一次滚动到底的时候,加载下一页,加载完之前,再怎么滚动,也不再执行加载下一页操作,加载完之后,重新响应滚动事件。
这么看来,我们关于保存的问题,应该是用防抖比较合适,因为我们要保证最后一个状态是被保存的。
之前跟同事说加节流,是我的错。
同事真的就从网上搜了个节流函数,加上了,结果不满足需求,作为一个开发,完全没有思考,也是有问题的。
其实我之前一直理解错了,我一直以为节流是第一次和最后一次都会执行。
对于我们的问题,也应该是第一次和最后一次都要执行。
我在第一次触发保存的时候,并不希望延迟保存,要立即执行,要避免频繁触发保存,最后一个保存一定要执行。
我不知道这个功能叫什么。但是我要满足这些需求,防抖和节流的结合。
实现代码(在同事代码基础上改的,我不太喜欢这种写法,不好读懂):
function throttle(fn, wait) { let timer = null let args; function a(){ timer = null; if(args) { console.log("------eee----", args); fn.apply(this, Array.prototype.slice.call(args, 0)); timer = setTimeout(a, wait); args = null; } } return function() { args = arguments; if (!timer) { a(); } } } function b(){ console.log(arguments); } var a = throttle(b, 2000); a("1"); setTimeout(function(){a("2");},1000); setTimeout(function(){a("3");},1500); setTimeout(function(){a("4");},4500);
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。