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

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

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

背景

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

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

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

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

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

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

另一个调用权重大的窗口是交易窗口              ,委托下单成功后会推送持仓数据                      、开仓价等              。委托单有几个状态:挂单       、部成(部分成交                     ,多次)或者已成(完全成交        ,一次)       ,部成状态和已成状态都会推送数据                     ,有推送就要调接口。那么部成的情况下就很容易短时间内(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
如何使用nginx(怎么使用Nginx实现HTTPS和SSL证书配置) 店员收款老板那提示吗(老板如何设置店员接受微信收款语音通知)