函數防抖(debounce)與函數節流(throttle)都是爲了限制函數的執行頻次,以優化函數觸發頻率太高致使的響應速度跟不上觸發頻率,出現延遲、假死或卡頓的現象。java
1、 函數防抖(debounce)git
概念github
函數防抖(debounce)是指在必定時間內,動做被連續頻繁觸發的狀況下,動做只會被執行一次,也就是說在事件被觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時。app
應用場景異步
對於函數防抖,主要應用場景爲如下幾種: 1. 給按鈕提交函數防抖阻止表單屢次提交 2. 對於輸入框連續輸入進行AJAX驗證時,用函數防抖能有效減小請求次數 3. 判斷scroll是否滑到底部,滾動事件+函數防抖 4. 表單驗證(用戶輸入時,驗證輸入的正確性) -總結來講,函數防抖適合屢次事件一次響應的狀況
源碼函數
function debounce(fn, wait) { var timer = null; return function () { var context = this var args = arguments if (timer) { clearTimeout(timer); timer = null; } timer = setTimeout(function () { fn.apply(context, args) }, wait) } }; var fn = function () { console.log('boom') } setInterval(debounce(fn,500),1000) // 第一次在1500ms後觸發,以後每1000ms觸發一次 setInterval(debounce(fn,2000),1000) // 不會觸發一次(我把函數防抖看出技能讀條,若是讀條沒完成就用技能,便會失敗並且從新讀條)
簡單實例fetch
在咱們項目中搜索框,存在用戶輸入文本,自動聯想匹配出一些接口供用戶選擇,咱們可能首先想到的作法是監聽輸入框的keyup事件,而後異步去查詢結果。可是存在這樣的狀況,若是用戶連續輸入n多個字符,那麼瞬間就會觸發10屢次請求,形成請求浪費。 咱們想要的是用戶中止輸入的時候纔去觸發查詢的請求,這時候防抖函數就能夠幫到咱們。優化
具體代碼實現以下this
請輸入搜索詞:<input type="text" id="search" list="search_list" name=""> <datalist id="search_list"></datalist> (function ($) { var $search = $('#search'); var $search_list = $('#search_list'); var timer = null; //定義定時器 $search.on('keyup', function () { timer && clearTimeout(timer); //若是定時器存在,清除定時器,中斷操做 timer = setTimeout(handleChange, 500); //發送異步請求 }); //輸入字段改變 function handleChange() { var s = $search.val(); $search_list.empty(); fetchBaiduSuggest(s, function (word, result) { result.map(function (w) { $('<option />').val(w).text(w).appendTo($search_list); }); }); } function fetchBaiduSuggest(word, cb) { $.getJSON("http://suggestion.baidu.com/su?wd=" + encodeURIComponent(word) + "&cb=?", function ( data) { if ($.isArray(data.s)) { cb(word, data.s); } }); } })(jQuery);
2、函數節流spa
函數節流是指必定時間內執行的操做只執行一次,也就是說即預先設定一個執行週期,當調用動做的時刻大於等於執行週期則執行該動做,而後進入下一個新週期,一個比較形象的例子是若是將水龍頭擰緊直到水是以水滴的形式流出,那你會發現每隔一段時間,就會有一滴水流出。
應用場景
源碼
function throttle(fn, gapTime) { let _lastTime = null; return function () { let _nowTime = new Date() if (_nowTime - _lastTime > gapTime || !_lastTime) { fn(); _lastTime = _nowTime } } } let fn = ()=>{ console.log('boom') } setInterval(throttle(fn,1000),10)
簡單實例
若是咱們如今須要作一個記錄用戶鼠標移動軌跡的小應用,像這種對流暢度有必定的要求的狀況,再用上面的防抖函數就不合適了,若是用防抖函數會出現什麼效果呢?若是鼠標移動速度較快,那麼只有在咱們每次鼠標停下來的時候才能發送當前的位置,可是若是咱們每次移動都發送並記錄鼠標的位置,那也是至關恐怖的,鼠標隨便移動一下就會有成百上千條記錄位置的請求發出去,這個時候咱們就能夠用到函數節流,節流顧名思義也就是個一段兒時間去發送一次位置,能夠大大減小請求發送次數。
<h2>函數節流</h2> <div> X: <span id='x'></span> Y: <span id='y'></span> </div> <script> (function($){ var $x = $('#x'); var $y = $('#y'); var isRun = true; $(document).on('mousemove',function(event){ var e = event || window.event; if(!isRun) return; // 判斷是否已空閒,若是在執行中,則直接return isRun = false; setTimeout(function(){ $x.text(e.pageX); $y.text(e.pageY); isRun = true; },100) }) })(jQuery);
3、總結
函數防抖和函數節流是在時間軸上控制函數的執行次數。函數節流和函數去抖的核心其實就是限制某一個方法被頻繁觸發,而一個方法之因此會被頻繁觸發,大多數狀況下是由於 DOM 事件的監聽回調,而這也是函數節流以及去抖多數狀況下的應用場景