一、防抖函數
1.1 概念:
觸發高頻事件后n秒內函數只會執行一次,如果n秒內高頻事件再次被觸發,則重新計算時間。
1.2 使用場景:
就像是我的搜索欄功能,是在里面內容變化后就實時觸發搜索事件,但是有時候我們輸
的內容很長,在沒有輸完的時候就觸發了事件,這樣對性能來說是不好的,造成了很多
無用的請求,這時候就需要用到防抖函數,來讓其在搜索內容變化后的200毫秒內如果
沒有再更改才發起請求。
1.3 實現防抖函數的思路:
在高頻觸發事件的時候,取消原來的延時事件。
1.4 具體實現:
function debounce( fn ){ // 傳一個回調函數 let Mytime = null ; return function( ){ clearTimeout( Mytime ) ; // 清除定時器 Mytime = setTimeout( () => { fn.apply(this,arguments) }, 200) } }
1.5 具體使用
function sayHi() { console.log('防抖成功'); } var select = document.getElementById('myselect'); select .addEventListener('change', debounce(sayHi)); // 防抖
二、節流函數
2.1 概念:
高頻事件觸發,但在n秒內只會執行一次,所以節流會稀釋函數的執行頻率;
2.2 使用場景:
就像我接了一個任務,只能在5秒完成任務給回復,在執行后的這5秒內,你再怎么給
我布置任務我都不管直接當沒聽到,直到到5秒后執行完這個任務,你才可以再次給
我布置任務,以此類推。。。
2.3 實現思路:
每次觸發事件時都判斷當前是否有等待執行的延時函數,如果有直接截斷事件不用往下執行了;
2.4 具體實現:
function throttle( fn ){ let canUse = true ; // 設置一個開關 return function(){ if(!canUse ){ return false } // 如果開關已經關掉了就不用往下了 canUse = false // 利用閉包剛進來的時候關閉開關 setTimeout( ( ) => { fn.apply(this,arguments)
canUse = true // 執行完才打開開關 },500) } }
2.5 具體使用:
function sayHi(e) { console.log(e.target.innerWidth, e.target.innerHeight); } window.addEventListener('resize', throttle(sayHi));
三、個人理解兩者的區別
防抖函數和節流函數的一個區別就是防抖是按照最后一次觸發為下一次事件執行的時間計算點,
前面的沒滿足間隔時間的都從最后這一次開始來決定什么時候執行延時事件;
而節流函數是按照第一次觸發事件作為時間計算點,后面沒到間隔時間的事件都忽略;