JS按钮连击和接口调用频率限制防止客户爆仓

 更新时间:2022年09月29日 09:22:19   作者:CatWatermelon  
这篇文章主要为大家介绍了JS按钮连击和接口调用频率限制防止客户集体爆仓详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

背景

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

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

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

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

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

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

另一个调用权重大的窗口是交易窗口,委托下单成功后会推送持仓数据、开仓价等。委托单有几个状态:挂单、部成(部分成交,多次)或者已成(完全成交,一次),部成状态和已成状态都会推送数据,有推送就要调接口。那么部成的情况下就很容易短时间内(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限制按钮连击接口调用的资料请关注程序员之家其它相关文章!

相关文章

  • JavaScript?this指向绑定方式及不适用情况详解

    JavaScript?this指向绑定方式及不适用情况详解

    这篇文章主要为大家介绍了JavaScript?this指向绑定方式及不适用情况详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Canvaskit快速入门教程

    Canvaskit快速入门教程

    这篇文章主要为大家介绍了Canvaskit快速入门教程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 微信小程序 底部导航栏目开发资料

    微信小程序 底部导航栏目开发资料

    这篇文章主要介绍了微信小程序 底部导航栏目开发资料的相关资料,微信小程序底部想要有一个漂亮的导航栏目,不知道怎么制作,于是百度找到了本篇文章,分享给大家,需要的朋友可以参考下
    2016-12-12
  • 微信小程序 Windows2008 R2服务器配置TLS1.2方法

    微信小程序 Windows2008 R2服务器配置TLS1.2方法

    微信小程序免费SSL证书https、TLS版本问题的解决方案《二十四》request:fail错误(含https解决方案)(真机预览问题把下面的代码复制到PowerShell里运行一下,然后重启服务器。# Enables TLS 1.2 on ...,需要的朋友可以参考下
    2016-12-12
  • 如何利用javascript做简单的算法

    如何利用javascript做简单的算法

    这篇文章主要介绍了如何利用javascript做简单的算法,主要是以提问的形式犹如练习小例子然后解决问题并附代码说明,需要的朋友可以参考一下
    2021-11-11
  • JS中的every()对空数组总返回true原理分析

    JS中的every()对空数组总返回true原理分析

    这篇文章主要为大家介绍了JS中的every()对空数组总返回true原理分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • JavaScript代码不能被阻断的稳定性建设

    JavaScript代码不能被阻断的稳定性建设

    这篇文章主要为大家介绍了JavaScript代码不能被阻断的稳定性建设详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • 详解节点监控相对准确的计算FMP

    详解节点监控相对准确的计算FMP

    这篇文章主要为大家介绍了节点监控相对准确的计算FMP详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 微信小程序 toast组件详细介绍

    微信小程序 toast组件详细介绍

    这篇文章主要介绍了 微信小程序 toast组件详细介绍的相关资料,需要的朋友可以参考下
    2016-09-09
  • 微信支付 JS API支付接口详解

    微信支付 JS API支付接口详解

    本文是对微信支付 JS API支付接口介绍,并附代码实例,在开发过程中具有参考价值,希望能帮助到需要的朋友
    2016-07-07

最新评论

?


http://www.vxiaotou.com