SAP UI5和Angular的函数防抖(Debounce)和函数节流(Throttle)实现原理介绍-阿里云开发者社区

开发者社区> 开发者小助手-bz4> 正文

SAP UI5和Angular的函数防抖(Debounce)和函数节流(Throttle)实现原理介绍

简介: SAP UI5和Angular的函数防抖(Debounce)和函数节流(Throttle)实现原理介绍
+关注继续查看

Angular

641 篇文章10 订阅

订阅专栏

这是Jerry 2021年的第 11 篇文章,也是汪子熙公众号总共第 282 篇原创文章。


Jerry之前的文章 SAP UI5 OData谣言粉碎机:极短时间内发送两个Odata request, 前一个会自动被cancel掉吗,介绍过SAP成都研究院CRM Fiori开发团队开发过的一个Live Search的场景。


用户创建Opportunity,维护Account字段,每输入一个字符,都会触发SAP UI5 Input控件的liveChange事件。在该事件的onAccountInputFieldChanged处理函数里,根据用户输入,发送OData请求到后台进行查询。


image.pngimage.png最近Jerry做SAP Spartacus开发,遇到了同样的场景。因此通过本文把自己最近所学总结一下,记录下SAP UI5和Angular里如何使用函数防抖(Debounce)和函数节流(Throttle)来避免短时间内触发高频次函数调用的情况出现。


为了便于讲解,Jerry做了一个只包含一个Input控件的SAP UI5页面。源代码地址.


在Input里输入字符,会触发liveChange事件,将当前Input的最新内容,发送到一个我自己开发的后台服务去。该后台服务什么也不做,只是简单将收到的内容返回给UI.


image.pngimage.pngimage.pngSAP UI5如何使用函数防抖(Debounce)来降低函数调用的频次

函数防抖(Debounce),最早源于机械开关和继电器的术语“去弹跳”,即将多个信号合并为一个信号。


想象一个大家现实生活中都会遇到的场景:进电梯。电梯都有一个自动关闭门的超时时间,假设为2秒。当电梯检测到有人进入时,会重置这个2秒的计时器。如果下一个2秒之内,没有新的乘客进入电梯,电梯门才会自动关上。



image.png电梯延迟关门这个场景,就是一个典型的函数防抖的现实例子。电梯关门的行为就是“函数”,通过电梯门的自动关闭超时时间,2秒,来延迟电梯门的关闭动作的执行,从而降低电梯门的关闭频率,这就是“防抖”。


可以想象,如果电梯门的自动关闭没有设定超时时间,而是检测到没有人进出之后,立即关闭,这样会大大增加电梯门开合的频率,既浪费能源,也不安全。这就好比Jerry本文开头提到的例子:既然我短时间内输入了字符1234,我期望在UI看到的,是后台服务接收到1234后返回的结果。至于后台如何对前三个请求,即字符1,字符12和字符123进行处理,我不再关心。


我们可以仿照电梯门关闭超时时间的设定,来给SAP UI5的函数调用实现防抖控制。


下图debounce变量是一个函数构造器,本身是一个函数,接收另一个函数fn作为输入参数,职责是通过闭包,将fn改造成一个具有防抖控制功能的新函数,该新函数通过第17行的return语句返回。


防抖时间间隔通过函数构造器另一个输入参数delay指定。


image.png假设我们指定的防抖时间间隔为3000毫秒即3秒,如果3秒之内,debounce函数构造器返回的新函数被不断调用,此时执行上图代码第19行,调用clearTimeout重置计数器,此时原始函数fn不会得到执行。这个场景可以类比成:在电梯关门超时时间内,又有新的乘客进入,电梯超时计时器重置,电梯门不会关闭。


代码第20行,使用setTimeout重启超时时间间隔为3秒的计数器,3秒过后,如果JavaScript任务队列里没有其他待执行任务,则执行原始函数fn. 代码的第20行,好比电梯设备重新开启了3秒的超时定时器。


如果在等待的3秒之内,没有新的函数调用触发,则3秒过后,执行21行的原始函数fn;这好比电梯在3秒之内,始终没有新的乘客进入,则 3秒过后,电梯门自动关闭。


debounce函数构造器的使用方式也很简单。


代码第78行,将原始的sendRequest函数,以及3000毫秒的防抖时间间隔,传入debounce构造器,返回一个兼有数据发送功能和防抖功能的debounceVersion函数。在第85行原来调用sendRequest函数的位置,改为调用debounceVersion函数即可。


image.pngimage.pngimage.pngSAP UI5如何使用函数节流(Throttle)来降低函数调用的频次

上述函数防抖的实现存在一个问题,还是以电梯的例子来说明。


设想有一个空间无限的电梯,关门的超时时间为3秒。如果不断的有新的乘客以小于3秒的时间间隔进入电梯,则电梯门永远没有机会关闭——即函数永远得不到执行。


函数节流(Throttle)是另一种降低函数调用频次的思路,同函数防抖的区别是,后者能保证在指定的节流间隔内,至少执行一次函数。


函数节流构造器的一个最简单的实现版本:


被节流器改造后的函数每次触发时,取一个当前系统时间戳,同前一次触发时取的时间戳比较。如果二者的时间差,大于等于构造器的输入参数delay即节流时间间隔,则进入第39行的else分支,触发原始函数fn;否则说明节流时间间隔还未到达,使用第34行setTimeout,将原始函数fn,重新放入JavaScript事件队列内,延迟执行:


image.png函数节流版本的构造器使用方式,同函数防抖版本的构造器没有差别:将原始函数sendRequest传入构造器throttle,返回一个具有节流功能的新函数throttleVersion,在Input控件liveChange事件处理函数里,调用throttleVersion这个新函数即可。


image.pngimage.png本文介绍的两种函数防抖和函数节流的实现代码,仅仅考虑了最基本的情况,还有很多不完善的地方,有兴趣的朋友可以在网络上搜索,这方面的资料非常多,这里不再赘述。


Jerry之前的分享提到过,Angular是响应式编程开发库RxJS的重度使用者,后者提供了众多功能强大的Operators,使得Angular开发人员不用重复造轮子,就能轻易实现出具有函数防抖和函数节流的场景。


image.png用Angular重新实现本文SAP UI5的Demo,总共代码只有44行:image.pngimage.png类似SAP UI5 Input控件的liveChange,Angular FormControl的valueChanges也给应用开发人员提供了编写业务逻辑,响应用户输入的位置:后者的valueChanges数据类型是Observable,应用开发人员可以通过pipe调用,传入RxJS各种功能强大的Operators,让自己编写的包含业务逻辑的事件响应函数,按照实际需求来触发。


image.png比如上图第39行代码,语义是:绑定到jerryFormControl的input控件有valueChanges发生时,首先经过防抖器的处理。至于是否能够满足触发valueChanges对应的事件处理函数的条件,由防抖器debounceTime的内部处理逻辑决定。


RxJS防抖器debounceTime的内部实现使用了setInterval,逻辑比Jerry本文介绍的debounce函数构造器复杂得多了,通过这些调用栈就能感受一二:


image.pngimage.pngimage.png

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9480 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
9048 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13163 0
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
7380 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
21887 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
4008 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6884 0
2315
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载