首页IT科技js点击按钮控制开始和停止的区别(JS按钮连击和接口调用频率限制防止客户爆仓)

js点击按钮控制开始和停止的区别(JS按钮连击和接口调用频率限制防止客户爆仓)

时间2025-06-20 14:10:23分类IT科技浏览4498
导读:背景 这个项目是一个货币交易客户端,后端会走币安的开放接口,而币安的接口每分钟调用次数是有阈值的,调多了直接接口返回错误。...

背景

这个项目是一个货币交易客户端            ,后端会走币安的开放接口                   ,而币安的接口每分钟调用次数是有阈值的       ,调多了直接接口返回错误             。

客户端里            ,有的窗口可能涉及 多个信息的查询                   ,而这些信息需要调用不同的币安的接口       ,因此后端有的接口调用起来 权重很大(存在一个接口需要调用币安十几个接口的情况)                   。

那么接口调用权重大的有两个窗口      ,其中一个是账户信息窗口      。

账户信息窗口需要实时的更新持仓盈亏以及强平价             、开仓价等信息                  ,这些信息分布在币安各个接口里             ,所以调用这个接口的 权重很大       。在这个窗口中我们添加了一个 强制刷新数据 按钮      ,用来 防止行情波动大 时卡住                  ,影响 数据实时性                   。

那么当时的我还是欠考虑             ,忘记 给按钮添加防抖操作了,带来的结果就是在网络状况不好的情况下                  ,有些比较急躁的用户会 连击                    ,这样会一直调用接口,权重很快就达到阈值了            。达到阈值后平仓平不了            ,亏钱甚至是爆仓                   ,只能干瞪眼      。

所以我们要 控制用户连击行为       ,这就要用到节流了                   。

另一个调用权重大的窗口是交易窗口            ,委托下单成功后会推送持仓数据                   、开仓价等            。委托单有几个状态:挂单      、部成(部分成交                  ,多次)或者已成(完全成交       ,一次)      ,部成状态和已成状态都会推送数据                  ,有推送就要调接口。那么部成的情况下就很容易短时间内(0.5s)达到完全成交             ,也就是说有可能 一个委托单会触发好几次的接口调用                    。这种客户端主要功能就是 下单 了      ,行情波动大的时候交易员都是快捷键操作                  ,一秒几单             ,这是达到阈值的主要原因,不节流等着提桶吧                  。

节流是什么

介绍了这么多                  ,有的小伙伴还不知道什么是“节流            ”                   ,或者是听过 防抖节流 ,但是一直对这两个概念混淆            ,接下来我额外给大家做个小科普。

想必很多人都有玩过 moba 游戏                   ,我拿大众点的 英雄联盟王者荣耀 来举例             。

节流:英雄是会释放技能的       ,技能释放完会有冷却 cd            ,如果没有冷却完毕                  ,不管你手按的再快       ,技能都放不出来                  。这个就是节流      ,一定时间疯狂连击我只触发一次      。

防抖:回城都知道吧                  ,王者荣耀里回城所需的时间是 7 秒             ,如果在回城过程中你再次点击回城      ,那么回城时间是会被重置的             。比如你点击回城过了 3 秒了                  ,这个时间手欠又点了一下回城             ,好了,原本只要再等 3 秒就能泡泉水                  ,这下你又要重新登 7 秒了                   。这个就是防抖      。

回归正题                   ,因为我希望的是 允许用户刷新,但是不能太频繁            ,最好是一段时间内只允许刷新一次                    ,是不是和上面防抖的例子一样       ,妥妥的防抖就安排上了嘛      。

如何节流

不使用节流

我们先使用一个简单的例子来讲                   。

逻辑就是鼠标在灰色 box 上移动时            ,不断递增数字            。

<style> .box { background-color: grey; height: 100px; display: flex; justify-content: center; align-items: center; font-size: 20px; color: #fff; } </style> <body> <div class="box" id="box">0</div> <script> const box = document.querySelector(#box); let count = 0; box.addEventListener(mousemove, ()=>{ box.innerHTML = ++count; }) </script> </body>

可以看到                  ,正常情况下 mousemove 事件会频繁触发      。如果换成接口调用会咋样?想都不敢想                   。

使用节流之后

我们的需求还是鼠标移动时       ,数字递增      ,不同的是我们希望数字增长不要太快(事件触发频繁不要太快)                  ,这就要用到防抖了            。

我们来改造一下代码:

const box = document.querySelector(#box); let count = 0; const throttle = (callback) => { let time = 0; return () => { const now = Date.now(); const diff = (now - time) / 1000; if(diff > 0.5) { callback(); time = now; } } } box.addEventListener(mousemove, throttle(()=>{ box.innerHTML = ++count; }))

其中             ,throttle 函数的返回值是一个函数      ,这个函数引用了外层变量 time                  ,形成了一个闭包。

变量 time 用来记录 上一次调用发生的时间              ,一开始默认为 0 ,这样下次触发就能 直接进行第一次调用                    。

后续触发事件回调时                  ,判断当前触发回调的时间和上一次触发回调的 时间差 是不是 大于 我们规定的时间(0.5s)                   ,如果大于则允许调用,否则本着节流的逻辑            ,这次调用显然不被允许了                  。

需要注意的是                   ,在允许调用的情况下       ,我们要 更新 time 的值为 now。

我们来看看改造后的效果:

模板

相信大家都看出来了            ,朴素的节流有一套模板:

const thrrotle = (callback) => { let time = 0; return () => { const now = Date.now(); const diff = (now - time) / 1000; if(diff > 0.5) { callback(); time = now; } } }

还有种节流是通过一个 flag 变量控制是否允许调用回调的:

function throttle(fn,delay) { let flag = true; return function() { if (flag) { setTimeout(() => { fn.call(this); // 绑定 this flag = true; }, delay); } flag = false; } }

示例

那么我项目中就是控制 10 秒内只允许触发一次接口调用                  ,因此这里的 0.5 我要改成 10             。

// 点击刷新按钮尝试刷新 const attempRefresh = (() => { let lastTime = new Date().getTime(); const delay = 10; return () => { const now = new Date().getTime(); const diff = (now - lastTime) / 1000; if (diff >= delay) { getAccountInfo(); // 调用接口 lastTime = now; } else { message.info({ content: `刷新过于频繁       ,请${delay - Math.floor(diff)}秒后尝试!`, key: EMessageKey.ACCOUNT_INFO, }); } }; })();

经过这么一改造      ,用户第一次点击刷新的时候是允许刷新的                  ,而在 10 秒内妄图再次刷新             ,展现给它的只有冰冷的提示语                  。

结束语

日常开发中      ,除了限制接口调用频率外                  ,像页面 scroll 事件      、窗口 resize 事件             ,为了性能考虑,都是需要进行节流处理的                  ,而看完本文                   ,相信大家都理解掌握了节流的方法,套用模板就完事了      。但是还是希望大家能吃透            ,毕竟代码也不多                   ,有了思路就不用去背代码了             。学到就是赚到                   。

以上就是JS按钮连击和接口调用频率限制防止客户爆仓的详细内容       ,更多关于JS限制按钮连击接口调用的资料请关注本站其它相关文章!

声明:本站所有文章            ,如无特殊说明或标注                  ,均为本站原创发布      。任何个人或组织       ,在未征得本站同意时      ,禁止复制                   、盗用            、采集      、发布本站内容到任何网站                   、书籍等各类媒体平台      。如若本站内容侵犯了原著者的合法权益                  ,可联系我们进行处理                   。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
python局部变量的规则(python局部变量是什么)