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

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

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

背景

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

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

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

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

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

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

另一个调用权重大的窗口是交易窗口                ,委托下单成功后会推送持仓数据                        、开仓价等                。委托单有几个状态:挂单        、部成(部分成交                        ,多次)或者已成(完全成交        ,一次)        ,部成状态和已成状态都会推送数据                        ,有推送就要调接口。那么部成的情况下就很容易短时间内(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
vue打包(解决vue中el-date-picker type=daterange日期不回显的问题)