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

目录
  • 背景
  • 节流是什么
  • 如何节流
    • 不使用节流
    • 使用节流之后
    • 模板
    • 示例
  • 结束语

背景

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

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

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

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

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

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

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

(0)

相关推荐

  • JavaScript DSL 流畅接口(使用链式调用)实例

    认真研究了一会DSL,发现了这么几件有趣的事,JavaScript用得最多的一个东西怕是链式调用 (方法链,即Method Chaining). 有意思的是Martin Flower指出: 复制代码 代码如下: I've also noticed a common misconception - many people seem to equate fluent interfaces with Method Chaining. Certainly chaining is a common tec

  • JS简单获取客户端IP地址的方法【调用搜狐接口】

    本文实例讲述了JS简单获取客户端IP地址的方法.分享给大家供大家参考,具体如下: <!doctype html> <html> <head> <meta charset="utf-8"> <title>使用搜狐接口获取客户端IP地址</title> </head> <body> <script src="http://pv.sohu.com/cityjson?ie=utf-8

  • 在JavaScript中调用Java类和接口的方法

    前言 本文中所有的代码使用 JavaScript 编写,但你也可以用其他兼容 JSR 223 的脚本语言.这些例子可作为脚本文件也可以在交互式 Shell 中一次运行一个语句的方式来运行.在 JavaScript 中访问对象的属性和方法的语法与 Java 语言相同. 本文包含如下几部分: 1.访问 Java 类 为了在 JavaScript 中访问原生类型或者引用 Java 类型,可以调用 Java.type() 函数,该函数根据传入的完整类名返回对应对象的类型.下面代码显示如何获取不同的对象类

  • js微信分享接口调用详解

    本文实例为大家分享了js微信分享接口调用的具体代码,供大家参考,具体内容如下 微信api直通车,仔细阅读官方文档问题都可以解决的 好吧,最近用到了,整理下发出来,就这个效果吧 1.设置js接口安全域名 这需要使用微信的jssdk,先需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名.打开这个页面之后你会看到下面的提示.需要先下载这个文件并上传到指定域名的根目录. 这个文件里面是一个字符串,从名称看是用来校验用的.先上传了这个文件,你才能保存成功.这样你就可以使用jss

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

    目录 背景 节流是什么 如何节流 不使用节流 使用节流之后 模板 示例 结束语 背景 这个项目是一个货币交易客户端,后端会走币安的开放接口,而币安的接口每分钟调用次数是有阈值的,调多了直接接口返回错误. 客户端里,有的窗口可能涉及 多个信息的查询 ,而这些信息需要调用不同的币安的接口,因此后端有的接口调用起来 权重很大(存在一个接口需要调用币安十几个接口的情况). 那么接口调用权重大的有两个窗口,其中一个是账户信息窗口. 账户信息窗口需要实时的更新持仓盈亏以及强平价.开仓价等信息,这些信息分布在

  • Laravel中GraphQL接口请求频率实战记录

    前言 起源:通常在产品的运行过程,我们可能会做数据埋点,以此来知道用户触发的行为,访问了多少页面,做了哪些操作,来方便产品根据用户喜好的做不同的调整和推荐,同样在服务端开发层面,也要做好"数据埋点",去记录接口的响应时长.接口调用频率,参数频率等,方便我们从后端角度去分析和优化问题,如果遇到异常行为或者大量攻击来源,我们可以具体针对到某个接口去进行优化. 项目环境: framework:laravel 5.8+ cache : redis >= 2.6.0 目前项目中几乎都使用的

  • 小程序按钮避免多次调用接口和点击方案实现(不用showLoading)

    本来是用showLoading的,点击直接转菊花,但是呢,showLoading和 showToast这个方法是冲突的,你转了菊花不能弹toast提示,在某个页面需要提交一次表单和做输入验证,测试说可以点击多次 然后想到可以用一个变量判断是否点击了,然后500毫秒后自动回来 写在公共的utils方法里面 // 防止多次点击 function btnClickedFun(self) { self.setData({ btnClicked: true }) setTimeout(() => { se

  • C#微信开发之获取接口调用凭据

    获取接口调用凭据 ①接口说明 access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留512个字符空间.access_token的有效期目前为2h(7200s),需定时刷新,重复获取将导致上次获取的access_token失效. 公众平台的API调用所需的access_token的使用及生成方式说明: 1.为了保密appsecrect,第三方需要一个access_token获取和刷新的中控

  • Vue2 配置 Axios api 接口调用文件的方法

    前情回顾 在上一篇中,我们通过配置基本的信息,已经让我们的项目能够正常的跑起来了.但是,这里还没有涉及到 AJAX 请求接口的内容. vue 本身是不支持 ajax 接口请求的,所以我们需要安装一个接口请求的 npm 包,来使我们的项目拥有这个功能. 这其实是一个重要的 unix 思想,就是一个工具只做好一件事情,你需要额外的功能的时候,则需要安装对应的软件来执行.如果你以前是一个 jquery 重度用户,那么可能理解这个思想一定要深入的理解. 支持 ajax 的工具有很多.一开始,我使用的是

  • 微信公众号H5支付接口调用方法

    本文实例为大家分享了 微信内H5调用支付接口的具体代码,供大家参考,具体内容如下 官方文档地址 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>微信公众号H5接口调用</title> <script src='./js/md5.js'></script> </head>

  • 详解IntelliJ IDEA 自带的 HTTP Client 接口调用插件吊打 Postman

    1 前言 当我们在开发调试 Web 服务的时候,需要对接口进行调用测试:或者对接第三方系统时,需要调用远程第三方的接口进行联调.这时,相信大家首选的工具一般会是 Postman ,一款当今比较流行而且功能齐全的接口调用调试工具.如下所示: 不过我们一般使用 IntelliJ IDEA 代码编辑器来开发和调试 Web 服务,如果使用 Postman 工具来测试接口,不仅要在电脑上安装 Postman ,还需要在不同工具之间切换,比较麻烦.幸运地的是 IDEA 自带了一款简洁轻量级的接口调用插件,H

  • Vue项目中接口调用的详细讲解

    在企业开发过程中,往往有着明确的前后端的分工,前端负责接收.使用接口,后端负责编写.处理接口. 对于前端如何使用接口,今天在Vue中进行讲解. 一个项目往往由这几个部分组成. 其中在src文件夹中, ,有这么些内容. 我们常常把接口文件,新建一个文件夹在src下,命名为api,api内的文件便是接口文件. 通常把后端的接口写在api文件夹下,自己命名为xxx.js // 登录 export function login(data) { return request({ url: '/api/co

  • js防止页面被iframe调用的方法

    本文实例讲述了js防止页面被iframe调用的方法.分享给大家供大家参考.具体实现方法如下: 一.问题描述: 有时候我们发会现自己的网站页面被别人调用并且一模一样,这个其实就是简单的iframe调用了,下面我来给大家介绍js防止页面iframe调用的方法总结吧,有需要的朋友可参考 二.解决方法: 防止自己的网页被人框架: top.location.href 最上层的地址 windows.location.href自己的地址 self指代当前窗口对象,属于window最上层的对象; locatio

随机推荐