稳住了,别抖!—— 看 GetX 的 Worker 如何防抖
前言
在前后端对接过程中,经常会遇到快速重复点击导致重复请求的问题,如果处理不好一方面容易产生垃圾数据,另一方面还增加了很多无谓请求,导致服务器请求数量过多。在 GetX 中,针对这种场景提供了一个 Worker 类以及几个勾子函数来解决这类问题。
场景 1:疯狂点击
举个例子,某些购物 App 会提供互动游戏,通过在限定时间内点击的次数来刷红包或优惠券(都是套路😎),这个时候我们会疯狂地点击天上掉下来的红包或者锦鲤,试想如果每次点击都请求后端,那如果是上万人都这么点击,服务器都会被点崩!对于这种情况,GetX
提供了一个 debounce
的勾子函数,这个函数在限定的时间内只会执行一次指定的回调动作:
其中 listener
为状态变量,callback
为状态变量 listener
改变时的回调方法,time
为限定时间。三个参数构成的结果是在小于time
的时间内,如果listener
持续在变化的话就不会执行 callback
。如果在超过time
时间长度内没有变更才会调用一次callback
。举个例子,我们一个计数器counter
,按如下方式设定:
然后有一个按钮每点击一次就给计数器的值加 1。如果手速够快,我们 1 秒钟可以点击很多次。这个时候假设我们要防抖,就可以将网络请求放到 callback
里,从而在限定的时间范围内,避免用于的疯狂点击造成过多网络请求,造成类似 DDos 的攻击效果。我们来看一下效果,见下图。
可以看到,我们疯狂点击的时候,回调函数并没有执行,而是停下来间隔一定时间(1 秒)才执行。通过这种方式可以减少无谓的请求。这种场景还可以用于搜索场合,当在输入的时候,因为内容在变化,我们不用请求后端数据,而等到用户输入结束之后再请求,这样体验更好而且也能减少后端请求。
场景 2:刷金币
在有些场合,我们需要限定一定时间内的请求次数,做类似限流的效果。比如,在点击按钮刷金币的行为,我们可以限制没 2 秒最多刷 1 次,这样 1 分钟内最多只能刷 30 次,在 GetX
中提供了一个 interval
的方法:
使用和 debounce
类似,只是会忽略间隔 time
时间范围内的变化,在状态变量发生变化且每隔 time 时间才会调用 1 次 callback
。同时增加了一个 condition
(一个返回true
或 false
的函数),只有在该函数返回 true
时才会执行 callback
(比如必须是 vip
才可以刷金币)。我们以计数器为例看看效果。
可以看到金币数每隔 1 秒才会增加 1,而且超过 10 之后就不再增加了。
其他 Worker 勾子函数
GetX 还提供了下面三种 Worker
勾子函数,函数的调用和 interval 一样。
once
:状态变量变化时只执行一次,比如详情页面的刷新只更新一次浏览次数。ever
:每次变化都执行,可以用于点赞这种场合everAll
:用于列表类型状态变量,只要列表元素改变就会执行回调。
Worker 使用注意事项
为避免Worker
反复被注册,应当在 GetxController
的构造方法或 onInit
声明周期注册,或者在 StatefulWidget
的 initState
中注册(不推荐)。注意的是,需要在 dispose
方法中调用Worker
的dispose
方法销毁 Worker
对象。
总结
本篇介绍了 GetX
的 Worker
类以及对应的勾子函数的使用,通过注册 Worker
可以用于应用的防抖和限流,从而防止误触发和降低服务器请求数以降低资源消耗。
版权声明: 本文为 InfoQ 作者【岛上码农】的原创文章。
原文链接:【http://xie.infoq.cn/article/3108e5a809a322bc4a3c10ce6】。文章转载请联系作者。
评论