防抖和節流

1.應用場景:

js的一些事件:如keyup、onresize、scroll、mousemove、mousehover等;還有相似於:手抖、手滑、手誤、服務器沒有響應或者響應慢等的重複點擊操做。html

(2019-03-21)優化成下面:前端

  • 防抖:
    • search搜索聯想,用戶在不斷輸入值時,用防抖來節約請求資源;
    • window觸發resize的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次;
    • 防止重複提交;
  • 節流:
    • 鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次);
    • 監聽滾動事件,好比是否滑到底部加載更多,用throttle來判斷。
  • 再增長一點:防抖和節流的做用
    • 爲了減小沒必要要的計算;
    • 不浪費資源;
    • 只在適合的時候進行計算。

2.共同點:

均是用來控制某個函數在必定時間內執行多少次的技巧。兩種方法都是用來提升前端性能,減輕瀏覽器壓力。面試

(2019-03-21)優化成下面:算法

防止某一時間頻繁觸發事件。瀏覽器

3.區別:

3.1 什麼是防抖(debounce)?

延時處理,在事件被觸發N秒後再執行回調,若是在這N秒內又被觸發,則從新開始計時。服務器

(2019-03-21)增長下面:app

  • 某一時間段內,只能觸發一次,週期內不能再次觸發,直到中止後,才能夠執行。
window.addEventListener('resize',function(e){
    var t;
    return function(){
        if(t) clearTimeout(t);
        t = setTimeout(function(){
            // do something...
        },500);
    }
}());

3.2 什麼是節流(throttle)?

讓一個函數沒法在很短期內連續調用,當上一次函數過了規定的這個時間段後,才能進行下一次該函數的調用。異步

(2019-03-21)增長下面:前端性能

  • 每隔一個週期,執行一次
function throttle(func, waitTime) {
    var timeout,
        previous = 0;
    return function() {
        context = this;
        args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, waitTime)
        }
    }
}

(2019-03-21)防抖和節流實現函數增長下面:函數

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>防抖與節流</title>
<style>
  #container {
      width:400px;
      height: 200px;
      line-height: 200px;
      text-align: center;
      color: #ffffff;
      background-color: #333;
      font-size: 30px;
  }
</style>
</head>
<body>
   <div id="container"></div>
</body>
<script>
    //防抖和節流的做用: 爲了減小沒必要要的計算,不浪費資源,只在適合的時候進行計算
    // var count = 1;
    // var container = document.getElementById('container');
    // function getUserAction(){
    //     //大量的算法、邏輯、異步、回調
    //     console.log(this);
    //     container.innerHTML = count++;
    // }
    // container.onmousemove = debounce(getUserAction,1000,true);

    // //防抖
    // function debounce(func,wait,flag){
    //     var timeout;
    //     var self = this;
    //     return function(){
    //         clearTimeout(timeout);
    //         if(flag){//開始邊界  就去就是作
    //             var callnow = !timeout;//callnow:當前狀態  
    //             timeout = setTimeout(function(){
    //                 timeout=null;
    //             },wait);
    //             if(callnow){
    //                 func.apply(self);
    //             }
    //         }else{
    //             timeout = setTimeout(function(){
    //                 func.apply(self);//爲啥this沒有表明 <div id="container"></div>?
    //             },wait);
    //         }
    //     }
    // }
    //能夠控制邊界
    // 開始邊界  與  結束邊界

    // 事件執行一個方法,返回一個方法


    //節流
    var count = 1;
    var container = document.getElementById('container');
    function getUserAction(){
        //大量的算法、邏輯、異步、回調
        container.innerHTML = count++;
    }
    container.onmousemove = throttle(getUserAction,5000);

    function throttle(func,wait){
        //用定時器或者時間戳都可以寫
        var prexious = 0;//用作標記
        return function(){
            var self = this;
            var now = +new Date();//+new Date() 返回13位的時間戳,毫秒數;將會調用Date原型上的valueOf方法,等同於Date原型上的getTime()方法
            if(now - prexious > wait){
                func.apply(self);
                prexious = now;
            }
        }
    }



</script>
</html>

4.文字舉例:

A同窗從B地到C地,防抖就至關於A同窗坐公交車(乘客源源不斷的刷卡上車,直到司機看見無人刷卡後,纔會發車,即一段時間內,回調函數只會調用一次,即觸發事件的最後一次);節流就至關於A同窗坐地鐵(在規定的停車,在規定的時間發車,即在一段時間內,會每隔一段時間調用一次)。

(2019-03-21)總感受這段文字解釋不太好理解,先劃掉吧~

5.結語:

  • 據說這是個高頻面試題,且先記下。
相關文章
相關標籤/搜索