web前端常見面試題解析之函數(shù)節(jié)流與防抖(一)

節(jié)流與防抖這兩個詞匯在面試的過程當(dāng)中出現(xiàn)的頻率是非常之高的!首先你要知道節(jié)流與防抖它并不是一門什么新的技術(shù),而是為解決某些問題所采取的一種程序手段而已。再說直白一些其所指的就是代碼優(yōu)化!那么它們要解決的問題是什么?用于解決用戶頻繁觸發(fā)事件執(zhí)行,而對DOM操作、資源加載等耗費性能的問題。該問題可能會導(dǎo)致界面卡頓,甚至瀏覽器崩潰,從而降低你的用戶體驗!

我們先來聊一聊函數(shù)節(jié)流究竟是個什么鬼?先來看下定義:

  • 函數(shù)節(jié)流指的是預(yù)定一個函數(shù),只有函數(shù)在大于等于執(zhí)行周期時才執(zhí)行,周期內(nèi)調(diào)用不執(zhí)行。

我們可以將這個定義進(jìn)行一下拆分:
1、所謂函數(shù)節(jié)流指的就是一個函數(shù)。
2、該函數(shù)的執(zhí)行需要一個周期進(jìn)行控制。
3、周期內(nèi)調(diào)用該函數(shù)不執(zhí)行,否則會執(zhí)行。

拆分完之后你會發(fā)現(xiàn),要想理解函數(shù)節(jié)流的重點便是周期二字。

周期即時間,在指定的時間內(nèi)不會執(zhí)行,超過了便執(zhí)行。就拿生孩子來講,需要十月懷胎,總不會一個月就生個寶寶出來吧!即使你能創(chuàng)造人類生育史的奇跡,一個月生個健康的寶寶,可一個月也是一個周期對吧!如果到現(xiàn)在你還感覺不太好理解,那么咱們來完成一個小例子,每點擊一次按鈕數(shù)字加1,如圖:


<body>
    <div>0</div>
    <input type="button" value="點我啊" />
    <script>
        var myShow = document.querySelector("div");
        var myBtn = document.querySelector("input");
        myBtn.onclick = function (ev) {
            myShow.innerText = parseInt(myShow.innerText)+1;
        }
    </script>
</body>

上面的代碼很簡單,它告訴我們,只要你速度夠快,點擊多少次事件便會執(zhí)行多少次!你發(fā)瘋的點擊,數(shù)字便會發(fā)瘋的增長!雖然你點的很爽,但是代碼這樣寫是有問題的!如果你的DOM渲染比較復(fù)雜的話定會造成性能的浪費,另外如果有人惡意攻擊的話,后果也是比較嚴(yán)重的,比如我可以在控制臺寫以下代碼:



你會發(fā)現(xiàn)數(shù)字變了,這肯定不是你想看到的!但這就是現(xiàn)實!如果你做的是商品搶購活動的話,是不是瞬間就木有啦?
還好我比較仁慈,寫的循環(huán)次數(shù)比較?。ㄈ绻阍偻竺婕由蠋讉€9的話,你的瀏覽器結(jié)果只有死路一條!不妨親愛的你可以試試看?。?,如果腳本多執(zhí)行幾次呢?
現(xiàn)在走到這一步,程序便需要優(yōu)化了。聰明的你可能會想:如果我給他加上一些時間的限制,讓其在指定的時間內(nèi)不允許觸發(fā)事件,一切不都迎刃而解了嗎?沒錯,這就是函數(shù)節(jié)流的核心思想!
js代碼優(yōu)化如下:

<script>
    var myShow = document.querySelector("div");
    var myBtn = document.querySelector("input");
    /*
    定義的節(jié)流函數(shù)
    func指定的時間結(jié)束后所執(zhí)行的函數(shù),
    wait指定的時間
    返回值為函數(shù)
    */
    function throttle(func, wait) {
        let previous = 0;
        return function() {
            let now = Date.now();
            let context = this;
            if (now - previous >= wait) {
                func.apply(context, arguments);
                // 函數(shù)執(zhí)行后更新 previous 值
                previous = now; 
            }
        }
    }
    function addOne() {
        myShow.innerText = parseInt(myShow.innerText)+1;
    }
    myBtn.onclick = throttle(addOne,1000);
</script>

程序運行,一切還是那么美好!以上代碼用到的throttle函數(shù),便是通過閉包封裝的節(jié)流函數(shù),其核心就是:讓一個函數(shù)不要執(zhí)行得太頻繁,減少一些過快的調(diào)用來節(jié)流。
未完,后面再來聊一聊防抖!
價值400元的前端電子書,總有一本適合你!別客氣,趕緊拿走拿走?。?/a>

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,621評論 1 32
  • 1、JS的數(shù)據(jù)類型只有浮點型,沒有整型。null,underfined,boolean,number,string...
    6e5e50574d74閱讀 2,482評論 2 1
  • 概念 函數(shù)防抖(debounce) 當(dāng)調(diào)用動作過n毫秒后,才會執(zhí)行該動作,若在這n毫秒內(nèi)又調(diào)用此動作則將重新計算執(zhí)...
    yuanjiex閱讀 679評論 0 1
  • 一、概念 函數(shù)節(jié)流和函數(shù)防抖,兩者都是優(yōu)化高頻率執(zhí)行js代碼的一種手段。 舊款電視機的工作原理,就是一行行得掃描出...
    木子川頁心閱讀 597評論 1 1
  • 目錄及簡介 十月的姑蘇城,已經(jīng)有了深深的秋意。中午的氣溫尚可稱得上溫暖,到了晚上,寒風(fēng)吹起,過往行人都不由得縮起了...
    南歌吟閱讀 1,390評論 5 31

友情鏈接更多精彩內(nèi)容