欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS按鈕連擊和接口調(diào)用頻率限制防止客戶爆倉(cāng)

 更新時(shí)間:2022年09月29日 09:22:19   作者:CatWatermelon  
這篇文章主要為大家介紹了JS按鈕連擊和接口調(diào)用頻率限制防止客戶集體爆倉(cāng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

這個(gè)項(xiàng)目是一個(gè)貨幣交易客戶端,后端會(huì)走幣安的開(kāi)放接口,而幣安的接口每分鐘調(diào)用次數(shù)是有閾值的,調(diào)多了直接接口返回錯(cuò)誤。

客戶端里,有的窗口可能涉及 多個(gè)信息的查詢 ,而這些信息需要調(diào)用不同的幣安的接口,因此后端有的接口調(diào)用起來(lái) 權(quán)重很大(存在一個(gè)接口需要調(diào)用幣安十幾個(gè)接口的情況)。

那么接口調(diào)用權(quán)重大的有兩個(gè)窗口,其中一個(gè)是賬戶信息窗口。

賬戶信息窗口需要實(shí)時(shí)的更新持倉(cāng)盈虧以及強(qiáng)平價(jià)、開(kāi)倉(cāng)價(jià)等信息,這些信息分布在幣安各個(gè)接口里,所以調(diào)用這個(gè)接口的 權(quán)重很大 。在這個(gè)窗口中我們添加了一個(gè) 強(qiáng)制刷新數(shù)據(jù) 按鈕,用來(lái) 防止行情波動(dòng)大 時(shí)卡住,影響 數(shù)據(jù)實(shí)時(shí)性。

那么當(dāng)時(shí)的我還是欠考慮,忘記 給按鈕添加防抖操作了,帶來(lái)的結(jié)果就是在網(wǎng)絡(luò)狀況不好的情況下,有些比較急躁的用戶會(huì) 連擊 ,這樣會(huì)一直調(diào)用接口,權(quán)重很快就達(dá)到閾值了。達(dá)到閾值后平倉(cāng)平不了,虧錢(qián)甚至是爆倉(cāng),只能干瞪眼。

所以我們要 控制用戶連擊行為 ,這就要用到節(jié)流了。

另一個(gè)調(diào)用權(quán)重大的窗口是交易窗口,委托下單成功后會(huì)推送持倉(cāng)數(shù)據(jù)、開(kāi)倉(cāng)價(jià)等。委托單有幾個(gè)狀態(tài):掛單、部成(部分成交,多次)或者已成(完全成交,一次),部成狀態(tài)和已成狀態(tài)都會(huì)推送數(shù)據(jù),有推送就要調(diào)接口。那么部成的情況下就很容易短時(shí)間內(nèi)(0.5s)達(dá)到完全成交,也就是說(shuō)有可能 一個(gè)委托單會(huì)觸發(fā)好幾次的接口調(diào)用 。這種客戶端主要功能就是 下單 了,行情波動(dòng)大的時(shí)候交易員都是快捷鍵操作,一秒幾單,這是達(dá)到閾值的主要原因,不節(jié)流等著提桶吧。

節(jié)流是什么

介紹了這么多,有的小伙伴還不知道什么是“節(jié)流”,或者是聽(tīng)過(guò) 防抖節(jié)流 ,但是一直對(duì)這兩個(gè)概念混淆,接下來(lái)我額外給大家做個(gè)小科普。

想必很多人都有玩過(guò) moba 游戲,我拿大眾點(diǎn)的 英雄聯(lián)盟王者榮耀 來(lái)舉例。

節(jié)流:英雄是會(huì)釋放技能的,技能釋放完會(huì)有冷卻 cd,如果沒(méi)有冷卻完畢,不管你手按的再快,技能都放不出來(lái)。這個(gè)就是節(jié)流,一定時(shí)間瘋狂連擊我只觸發(fā)一次。

防抖:回城都知道吧,王者榮耀里回城所需的時(shí)間是 7 秒,如果在回城過(guò)程中你再次點(diǎn)擊回城,那么回城時(shí)間是會(huì)被重置的。比如你點(diǎn)擊回城過(guò)了 3 秒了,這個(gè)時(shí)間手欠又點(diǎn)了一下回城,好了,原本只要再等 3 秒就能泡泉水,這下你又要重新登 7 秒了。這個(gè)就是防抖。

回歸正題,因?yàn)槲蚁M氖?允許用戶刷新,但是不能太頻繁,最好是一段時(shí)間內(nèi)只允許刷新一次 ,是不是和上面防抖的例子一樣,妥妥的防抖就安排上了嘛。

如何節(jié)流

不使用節(jié)流

我們先使用一個(gè)簡(jiǎn)單的例子來(lái)講。

邏輯就是鼠標(biāo)在灰色 box 上移動(dòng)時(shí),不斷遞增數(shù)字。

<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 事件會(huì)頻繁觸發(fā)。如果換成接口調(diào)用會(huì)咋樣?想都不敢想。

使用節(jié)流之后

我們的需求還是鼠標(biāo)移動(dòng)時(shí),數(shù)字遞增,不同的是我們希望數(shù)字增長(zhǎng)不要太快(事件觸發(fā)頻繁不要太快),這就要用到防抖了。

我們來(lái)改造一下代碼:

    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 函數(shù)的返回值是一個(gè)函數(shù),這個(gè)函數(shù)引用了外層變量 time,形成了一個(gè)閉包。

變量 time 用來(lái)記錄 上一次調(diào)用發(fā)生的時(shí)間 ,一開(kāi)始默認(rèn)為 0 ,這樣下次觸發(fā)就能 直接進(jìn)行第一次調(diào)用

后續(xù)觸發(fā)事件回調(diào)時(shí),判斷當(dāng)前觸發(fā)回調(diào)的時(shí)間和上一次觸發(fā)回調(diào)的 時(shí)間差 是不是 大于 我們規(guī)定的時(shí)間(0.5s),如果大于則允許調(diào)用,否則本著節(jié)流的邏輯,這次調(diào)用顯然不被允許了。

需要注意的是,在允許調(diào)用的情況下,我們要 更新 time 的值為 now。

我們來(lái)看看改造后的效果:

模板

相信大家都看出來(lái)了,樸素的節(jié)流有一套模板:

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

還有種節(jié)流是通過(guò)一個(gè) flag 變量控制是否允許調(diào)用回調(diào)的:

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

示例

那么我項(xiàng)目中就是控制 10 秒內(nèi)只允許觸發(fā)一次接口調(diào)用,因此這里的 0.5 我要改成 10。

// 點(diǎn)擊刷新按鈕嘗試刷新
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(); // 調(diào)用接口
      lastTime = now;
    } else {
      message.info({
        content: `刷新過(guò)于頻繁,請(qǐng)${delay - Math.floor(diff)}秒后嘗試!`,
        key: EMessageKey.ACCOUNT_INFO,
      });
    }
  };
})();

經(jīng)過(guò)這么一改造,用戶第一次點(diǎn)擊刷新的時(shí)候是允許刷新的,而在 10 秒內(nèi)妄圖再次刷新,展現(xiàn)給它的只有冰冷的提示語(yǔ)。

結(jié)束語(yǔ)

日常開(kāi)發(fā)中,除了限制接口調(diào)用頻率外,像頁(yè)面 scroll 事件、窗口 resize 事件,為了性能考慮,都是需要進(jìn)行節(jié)流處理的,而看完本文,相信大家都理解掌握了節(jié)流的方法,套用模板就完事了。但是還是希望大家能吃透,畢竟代碼也不多,有了思路就不用去背代碼了。學(xué)到就是賺到。

以上就是JS按鈕連擊和接口調(diào)用頻率限制防止客戶爆倉(cāng)的詳細(xì)內(nèi)容,更多關(guān)于JS限制按鈕連擊接口調(diào)用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論