函式節流與函式防抖

2021-10-16 13:19:26 字數 2247 閱讀 9542

再舉個栗子,假設電梯一次只能載一人的話,10 個人要上樓的話電梯就得走 10 次,是一種浪費資源的行為;而實際生活正顯然不是這樣的,當電梯裡有人準備上樓的時候如果外面又有人按電梯的話,電梯會再次開啟直到滿載位置,從電梯的角度來說,這時一種節約資源的行為(相對於一次只能載乙個人)。

這裡以判斷頁面是否滾動到底部為例,普通的做法就是監聽window物件的scroll事件,然後再函式體中寫入判斷是否滾動到底部的邏輯:

這樣做的乙個缺點就是比較消耗效能,因為當在滾動的時候,瀏覽器會無時不刻地在計算判斷是否滾動到底部的邏輯,而在實際的場景中是不需要這麼做的,在實際場景中可能是這樣的:在滾動過程中,每隔一段時間在去計算這個判斷邏輯。而函式節流所做的工作就是每隔一段時間去執行一次原本需要無時不刻地在執行的函式,所以在滾動事件中引入函式的節流是乙個非常好的實踐:

加上函式節流之後,當頁面再滾動的時候,每隔300ms才會去執行一次判斷邏輯。

簡單來說,函式的節流就是通過閉包儲存乙個標記(canrun = true),在函式的開頭判斷這個標記是否為true,如果為true的話就繼續執行函式,否則則 return 掉,判斷完標記後立即把這個標記設為false,然後把外部傳入的函式的執行包在乙個settimeout中,最後在settimeout執行完畢後再把標記設定為true(這裡很關鍵),表示可以執行下一次的迴圈了。當settimeout還未執行的時候,canrun這個標記始終為false,在開頭的判斷中被 return 掉。

很明顯,這樣的做法不好的是當使用者輸入第乙個字元的時候,就開始請求判斷了,不僅對伺服器的壓力增大了,對使用者體驗也未必比原來的好。而理想的做法應該是這樣的,當使用者輸入第乙個字元後的一段時間內如果還有字元輸入的話,那就暫時不去請求判斷使用者名稱是否被占用。在這裡引入函式防抖就能很好地解決這個問題:

其實函式防抖的原理也非常地簡單,通過閉包儲存乙個標記來儲存settimeout返回的值,每當使用者輸入的時候把前乙個settimeoutclear 掉,然後又建立乙個新的settimeout,這樣就能保證輸入字元後的interval間隔內如果還有字元輸入的話,就不會執行fn函式了。

function debounce(fn, interval = 300) , interval);};}

其實函式節流與函式防抖的原理非常簡單,巧妙地使用settimeout來存放待執行的函式,這樣可以很方便的利用cleartimeout在合適的時機來清除待執行的函式。

函式防抖與函式節流

函式防抖 debounce 當呼叫動作過n毫秒後,才會執行該動作,若在這n毫秒內又呼叫此動作則將重新計算執行時間 函式節流 throttle 預先設定乙個執行週期,當呼叫動作的時刻大於等於執行週期則執行該動作,然後進入下乙個新週期 函式節流 throttle 與函式防抖 debounce 都是為了限...

函式節流與函式防抖

這裡以判斷頁面是否滾動到底部為例,普通的做法就是監聽window物件的scroll事件,然後再函式體中寫入判斷是否滾動到底部的邏輯 這樣做的乙個缺點就是比較消耗效能,因為當在滾動的時候,瀏覽器會無時不刻地在計算判斷是否滾動到底部的邏輯,而在實際的場景中是不需要這麼做的,在實際場景中可能是這樣的 在滾...

函式防抖與函式節流

前言 有一些瀏覽器事件我們不希望它很頻繁的觸發,如調整視窗大小 onresize 監聽滾動條滾動 onscroll 如果這些監聽事件需要呼叫介面的話一秒內可能會呼叫上百次,這樣坑定是有問題的。函式防抖 debounce 如果有人進電梯 觸發事件 那電梯將在10秒鐘後出發 執行事件 這時如果又有人進電...