防抖和節流

前端開發中,咱們的一些事件的響應比較慢或者須要請求接口完成的,咱們不但願這些事件頻繁執行,好比說須要對input輸入的數據保存,監聽keyup事件,若是每次鍵盤輸入就執行保存請求,那樣可能會產生不少頻繁的請求,針對這種連續觸發的高頻率事件,函數防抖和函數節流給出了兩種解決方法前端

防抖(debounce)

去抖動,方法是在函數觸發時,設定一個週期延遲執行函數,若在週期內函數再次執行、則刷新延遲時間,直到最後執行函數,這裏函數收集到的結果是最後一次操做的結果bash

簡單的實現

var timer; // 定時器
function change (e) {
    if (timer) {
        clearTimeout(timer);
    }
    timer = setTimeout(function () {
        console.log(e.target.value);
        timer = void 0;
    }, 1000)
}
document.querySelector("#test").addEventListener('keyup', change);
複製代碼

這裏監聽input的keyup事件,change方法執行的時候會首先判判定時器是否存在、若是存在則clear掉,若是不則新建一個定時器延遲1s執行app

封裝

上面這樣實現沒毛病,可是卻有一個問題,沒有複用性,如今我來把他封裝成一個公共的方法函數

function keyup (e) {
    console.log(e.target.value);
}

function debounce (method, delay) {
    var timer = void 0;
    return function () {
        var self = this;
        var args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self, args)
            timer = void 0;
        }, delay)
    }
}
document.querySelector("#test").addEventListener('keyup', debounce(keyup, 1000));
複製代碼

節流(throttling)

節流的概念是設定一個週期,週期內只執行一次,如有新的事件觸發則不執行,週期結束後又有新的事件觸發開始新的週期ui

實現

好比說咱們監聽onscroll判斷獲取當前的scrollTop、能夠用到節流this

var start, timer, wait = 200
function scroll() {
    var self = this;
    var args = arguments;
    if (!start) {
        //第一次觸發,設置start時間
        start = Date.now()
    }
    // 當前時間減去開始時間大於等於設定的週期則執行而且初始化start、timer
    if (Date.now() - start >= wait) {
        console.log('觸發了')
        start = timer = void 0;
    } else {
        timer && clearTimeout(timer)
        timer = setTimeout(function () {
            scroll.apply(self, arguments)
        },wait)
    }
}
document.addEventListener('scroll', scroll)
複製代碼

封裝

function throttling (method, wait) {
    var start, timer
    return function run () {
        var self = this;
        var args = arguments;
        if (!start) {
            start = Date.now();
        }
        if (Date.now() - start >= wait) {
            method.apply(self, args)
            start = timer = void 0
        } else {
            timer && clearTimeout(timer)
            timer = setTimeout(function () {
                run.apply(self, args)
            }, wait)
        }
    }
}
function scroll() {
    console.log('觸發了')
}
document.addEventListener('scroll', throttling(scroll, 200))
複製代碼

這裏須要注意的就是參數和this指向的問題spa

總結

節流和防抖各有特色,若是是須要一連串頻繁的事件只執行最後一次選擇防抖、其它能夠選擇節流,具體業務具體分析code

若文中有錯誤的地方望多多指正接口

相關文章
相關標籤/搜索