函數節流與函數去抖

問題由來:html

在項目應用PeoplePicker控件的時候忽然聯想到一個問題,在輸入人名時不停的向後臺發請求,取到數據庫裏面的數據。咱們都知道頻繁的通訊會致使頁面效率下降。可不能夠設置個間隔,每次這個間隔通訊一次而不是每次輸入一個字符就通訊一次呢。其實這裏還有不少場景,好比resize事件,scroll事件。都會讓一個回調函數不停的執行。頁面操做成本是很是高的,若是不停的執行頁面效率會打打折損。因而產生了兩種解決方案:函數節流、函數去抖。數據庫

函數節流:閉包

頻繁的調用一個函數,咱們能夠添加一些限制,能夠緩解頻繁調用,咱們能夠設置個時間間隔,每次到時間調用一次。app

代碼:dom

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
</head>

<body>
    <input id="search" type="text" name="search">
    <script>
        function queryData(text) {
            console.log(text);
        }
        var input = document.getElementById("search");
        var handler = throttle(queryData, 1000);
        input.addEventListener("keyup", function (event) {
            handler(this.value);
        });
        function throttle(fn, delay) {
            var self = this,
                lastTime = 0,
                timer;
            return function (value) {
                var now = new Date().getTime();
                if (now - lastTime <= delay) {
                    return;
                }
                lastTime = now;
                clearTimeout(timer);
                timer = setTimeout(function () {
                    timeout = null;
                    fn.apply(self, [value]);
                }, delay)
            }
        }
    </script>
</body>

</html>

思路:利用閉包函數throttle保存timer以及lastTime,若是兩次的調用時間間隔小於設置的規定時間,就不去調用目標函數,若是大於這個時間間隔,就去設置一個timer,而後執行這個函數。這樣作的目的能夠達到頻繁調用函數,可是須要在一段時間纔回去執行該函數,這種方式就叫作函數節流。函數

效果:優化

一直不停的輸入,沒1秒會打一次log。this

函數去抖:spa

去抖能夠理解成爲是節流的一種狀況,在一個條件內函數一直不執行,直到調出該條件。code

代碼:

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
</head>

<body>
    <input id="search" type="text" name="search">
    <script>
        function queryData(text) {
            console.log(text);
        }
        var input = document.getElementById("search");
        var handler = debounce(queryData, 5000);
        input.addEventListener("keyup", function (event) {
            handler(this.value);
        });
        function debounce(fn, delay) {
            var timer,
                self = this;
            return function (value) {
                clearTimeout(timer);
                timer = setTimeout(function () {
                    timer = null;
                    fn.apply(self, [value]);
                }, delay);
            };
        }
    </script>
</body>

</html>

思路:函數調用n秒後纔會執行,若是函數在n秒內被調用的話,則函數不執行,從新計算執行時間。

效果:

不停的輸入不會打出log,中止輸入打出log。

總結:函數節流在必定程度上能夠優化頁面效率,減小不必的dom渲染以及http請求,更重要的是對js能夠有一個更深刻的理解。

相關文章
相關標籤/搜索