前端 JavaScript 之『节流』的简单代码实现
前戏
首先,总结一下上一篇文章——《前端 JavaScript 之『防抖』的简单代码实现》的内容:「防抖」就是在高频率触发事件停止触发后,延时执行某个处理逻辑。
防抖虽然在一定程度上对性能起到了优化效果,但是,我们也要看到它的局限性:如果高频率事件一直触发,那么回调函数中的逻辑就一直得不到执行。
大家都知道,掘金的编辑器带有草稿箱的效果,即你输入的内容会保存下来,即使我们退出编辑器页面了,再次进入还是可以找回前面输入的内容,这是因为编辑器的 input 事件中执行了发送内容的防抖函数。如下图所示:
现在假设:你的打字速度很快,基本上不带喘口气的,那么是否会导致很长时间都保存不了一次数据?如果这时候你再以迅雷不及掩耳之势关闭掉浏览器,是不是你所写的内容就保存不下来了?
那么我们是否可以想办法避免上面这种情况呢?
在这种需求背景下,我们今天的主人公——「节流」开始粉墨登场。
节流的含义大家应该都知道了:每隔固定的时间都会执行一次回函函数中的逻辑。
不使用节流函数,我们来看一下下面这个功能的执行效果:
<body> <form action="" class="example-form"> <div> <label for="name"> 名称 </label> <input class="input-ele" type="text" name="name" id="name" placeholder="please input your name" autocomplete="off"> </div> <div> <label for="res"> 输入 </label> <textarea class="input-ele" type="multipart" name="res" id="res" readonly placeholder="这里是每一次输入的结果"></textarea> </div> </form> </body> <script> window.onload = () => { const inputEle = document.querySelector("#name"); const resEle = document.querySelector("#res"); inputEle.addEventListener("input", function (event) { console.log(this.value); resEle.value += `\n${ this.value }` }); } </script>
实现的效果如下:
即使我们想要执行输出逻辑,但是也不能接受这么高频率的输出,一个是造成了输出内容冗余,二是渲染强度高,不太划算。
新需求
假如,现在有这么一个新需求,要我们在 input 事件中加入新的逻辑:每隔一段时间后,都会执行一次回调函数中的逻辑。
这个需求是不是挺符合节流函数的使用场景的,那我们赶紧来实现一个吧。
实现节流
根据节流函数的定义:以固定的低频率执行代码逻辑,具体到我们上面的额需求来说,只要打开页面,不管你有没有输入,都会每隔几秒就执行一次保存数据的逻辑。
window.onload = function () { const resEle = document.querySelector("#res"); function changeOutputVal(value) { resEle.value += `\n${ value }`; } function throttle(fun, delay) { let last, deferTimer return function (args) { let that = this; let _args = arguments; let now = +new Date(); if (last && now < last + delay) { clearTimeout(deferTimer); deferTimer = setTimeout(function () { last = now; fun.apply(that, _args); }, delay) } else { last = now; fun.apply(that, _args); } } } const outputRes = throttle(changeOutputVal, 2000); const inputEle = document.querySelector("#name"); inputEle.addEventListener("input", (eve) => { outputRes(eve.target.value); }); }
代码说明:
- 每一次事件被触发,都会判断间隔时间是否大于等于 delay,如果是,则执行输出逻辑;如果否,则清除原先的延时器,重新计算延时时间;
运行效果如下:
可以看到,在加入节流代码之后,输出事件不会每次 input 事件都触发,而是每隔 delay 时间触发一次。
~
~
代码比较粗糙,也比较基础,后面会逐步向着复杂的方向迭代,望各位看官海涵🙏
~
~
~ 本文完
学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!
大家好!我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!
知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
🏆Java技术专题-JVM实战案例(1)服务发生OOM故障定位方案
前提概要 对于JVM服务而言出现了OOM(Out Of Memory)问题,并且对其进行相关的解决是作为一个Java技术栈人员必备的实战能力。在此总结了一些相对通用的方案,希望能帮助到大家。 分析原因 某Java服务出现了OOM,最常见的原因为: 有可能是内存分配确实过小,而正常业务使用了大量内存(正常现象) 某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽(内存泄漏、代码问题) 某一个资源被频繁申请,系统资源耗尽,例如:不断创建线程,不断发起网络连接(线程不断创建、代码问题) 排查方案 确认是不是内存本身就分配过小 方法:jmap -heap pid 如上图,可以查看新生代,老生代堆内存的分配大小以及使用情况,看是否本身分配过小。 找到最耗内存的对象 方法:jmap -histo:live 10765 | more 如上图,输入命令后,会以表格的形式显示存活对象的信息,并按照所占内存大小排序: 实例数 所占内存大小 类名 是不是很直观?对于实例数较多,占用内存大小较多的实例/类,相关的代码就要针对性review了。 上图中占内存最多的对象是RingBufferLogEve...
- 下一篇
Redis源码剖析之GEO——Redis是如何高效检索地理位置的?
Redis GEO 用做存储地理位置信息,并对存储的信息进行操作。通过geo相关的命令,可以很容易在redis中存储和使用经纬度坐标信息。Redis中提供的Geo命令有如下几个: geoadd:添加经纬度坐标和对应地理位置名称。 geopos:获取地理位置的经纬度坐标。 geodist:计算两个地理位置的距离。 georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。 georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。 geohash:计算一个或者多个经纬度坐标点的geohash值。 要理解Redis的GEO相关的命令是如何实现了,就得先理解geohash的原理,本质上这些命令就是对geohash数据的封装而已。 geohash geohash是2008年Gustavo Niemeye发明用来编码经纬度信息的一种编码方式,比如北京市中心的经纬度坐标是116.404844,39.912279,通过12位geohash编码后就变成了wx4g0cg3vknd,它究竟是如何实现的?其实原理非常简单,就是二分,整个编码过程可以分...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7,CentOS8安装Elasticsearch6.8.6
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池