震驚!拉動一下控制檯大小,後臺請求數量爆炸,竟是沒作好防抖與節流!!

前言

最近有個朋友在面試過程當中遇到一個問題:什麼是防抖節流?糟了,這可觸碰到個人知識盲區了,好像聽也沒聽過這2個東西,痛定思痛,趕忙學習學習。javascript


防抖(debounce)

在事件被觸發n秒以後執行,若是在此期間再次觸發事件,則從新開始計時。html

乍一看,這不是閒的蛋疼嗎?爲啥要等n秒以後再執行呢?vue

本着存在即合理的原則,咱看不懂但咱得去學啊!通過十秒鐘的思考,忽然想起來以前作過的公司的一個小程序,使用的 mpvue+ vant-weappvan-field標籤並無和數據進行雙向綁定,而是每次都要觸發 @input事件,從而完成數據綁定:

這就致使了一個問題:

輸一個手機號要觸發11次事件!!若是是聯想搜索的話。。。那畫面太美!

咱們先本身想一下辦法來解決這個問題。java

  • 首先咱們須要在手機號輸入完成以後將數據綁定到phoneNumber上而後進行聯想搜索,怎麼算輸入完成呢,輸入一個數字到找到下一個數字輸入大概須要1不到秒,只要用戶一秒內沒有再次輸入,則將輸入框內容與phoneNumber綁定並進行聯想搜索(什麼?你說你輸入五個字符就停下?不怕後臺砍死你)
  • 準備工具:一個須要觸發的函數debounce、一個定時器、一個輸入框、一個判斷是否輸入完成的函數getPhone
  • 基本思路:輸入綁定事件getPhone,輸入以後開啓1秒定時器,若是在1秒內再次進行了輸入,則清除以前的定時器,而且從新設置定時器;若是1秒內沒有輸入,則輸入結束觸發事件a,進行聯想搜索。
<input id="phone" type="text"/>
複製代碼
// 須要觸發的函數
function debounce(d){
    console.log("聯想搜索phoneNumber:" + d)
}
let inp = document.querySelector("#phone");
// 輸入觸發的事件
function getPhone(fn,delay){
    let timer;
    // 使用閉包,保證每次使用的定時器是同一個
    return (d)=>{
        clearTimeout(timer);
        timer = setTimeout(()=>{
            fn(d);
            // 結束以後清除定時器
            clearTimeout(timer);
        },delay)
    }
}

let getPhoneDebounce = getPhone(debounce,1000);

inp.addEventListener('keyup',(e)=>{
    getPhoneDebounce(e.target.value);
})
複製代碼

這時候看輸出:面試

是的只輸出了一次號碼,也就是說不用每次輸入都進行一次搜索了。

節流(throttle)

若是持續觸發一個事件,則在必定的時間內只執行一次事件。小程序

那麼問題來了,既然是持續觸發了,那爲啥還要設定必定時間內只執行一次呢?廢話,你吃雞爲啥不用AKM非要去追夢搶狗雜呢?還不是由於AKM射速慢(狗雜真香)!閉包

咱們來試着作一個AKM的設計模擬:app

  • 首先第一次點擊射擊的時候,打出一發子彈,當以極短的時間再次點擊射擊的時候,因爲須要‘冷卻’——也就是節流,再次點擊無效,當冷卻時間過了以後,再次點擊射擊,則繼續下一次射擊
  • 準備工具:一個射擊的函數shot, 一個判斷射擊間隔是否結束的函數nextShot,一個觸發射擊的按鈕,判斷射擊是否結束的定時器timer
  • 基本思路:第一次點擊按鈕的時候,觸發shot,當繼續點擊的時候,射擊無效,只有過了定時器設置的時間才能夠繼續射擊。
<button id="shot">射擊</button>
複製代碼
function shot(){
    console.log('射擊')
}
let btn = document.querySelector('#shot');
function nextShot(fn,delay){
    let timer;
    // 閉包原理同上
    return ()=>{
        // 定時器存在,沒法射擊
        if(timer){
            console.log('禁止射擊');
        }else{  // 定時器不存在,射擊,並設置定時器
            fn();
            timer = setTimeout(()=>{
                // 定時器結束,能夠射擊
                clearTimeout(timer);
                timer = null;
            },delay)
        }
    }
}
let start = nextShot(shot,20);
btn.addEventListener('click',()=>{
    start();
})
複製代碼

當咱們瘋狂點擊按鈕的時候:函數

可能這個例子不是很突出,我再說個相似的,英雄聯盟和DNF的技能冷卻應該更適合~工具

是時候迴歸一下標題了,省得有人說我能夠去UC震驚部了

公司的大數據組件目前是隻要頁面大小發生變化就會從新加載,這就致使了有時候拉一下控制檯會發生不少次請求,這個時候就能夠用防抖來解決一下了~

相關文章
相關標籤/搜索