JS中的函數節流
一、什麼是函數節流(throttle)
概念:限制一個函數在一定時間內只能執行一次。
舉個栗子,坐火車或地鐵,過安檢的時候,在一定時間(例如10秒)內,只允許一個乘客通過安檢入口,以配合安檢人員完成安檢工作。上例中,每10秒內,僅允許一位乘客通過,分析可知,“函數節流”的要點在於,在 一定時間 之內,限制 一個動作 只 執行一次 。
二、爲什麼需要函數節流
前端開發過程中,有一些事件或者函數,會被頻繁地觸發(短時間按內多次觸發),最常見的例如,onresize,scroll,mousemove ,mousehover 等,這些事件的觸發頻率很高,不做限制的話,有可能一秒之內執行幾十次、幾百次,如果在這些函數內部執行了其他函數,尤其是執行了操作 DOM 的函數(瀏覽器操作 DOM 是很耗費性能的),那不僅會造成計算機資源的浪費,還會降低程序運行速度,甚至造成瀏覽器卡死、崩潰。這種問題顯然是致命的。
除此之外,重複的 ajax 調用不僅可能會造成請求數據的混亂,還會造成網絡擁塞,佔用服務器帶寬,增加服務器壓力,顯然這個問題也是需要解決的。
三、函數節流如何解決上述問題
根據上面對問題的分析,細細思索,問題的解決方案就呼之欲出了。
主要實現思路就是通過 setTimeout 定時器,通過設置延時時間,在第一次調用時,創建定時器,寫入需要執行的函數。第二次調用時,會清除前一個定時器並設置新的定時器。如果這時前一個定時器暫未執行,則將其替換爲新的定時器。目的在於在一定的時間內,保證多次函數的請求只執行最後一次調用。
四、函數節流的代碼實現
根據以上分析,我們對“函數節流”進行代碼實現,如下:
(1)方法一:時間戳方案
// 時間戳方案
function throttle(fn,wait){
var pre = Date.now();
return function(){
var context = this;
var args = arguments;
var now = Date.now();
if( now - pre >= wait){
fn.apply(context,args);
pre = Date.now();
}
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("mousemove",throttle(handle,1000));
(2)方法二:定時器方案
// 定時器方案
function throttle(fn,wait){
var timer = null;
return function(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
fn.apply(context,args);
timer = null;
},wait)
}
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("mousemove",throttle(handle,1000));
以上兩種方法本人都親自測試過,小夥伴們可以放心食用(注意,例子中函數觸發方式爲“ mousemove ”,鼠標在頁面上移動,觀察瀏覽器控制檯的變化),自己運行代碼體驗後,自然會更深刻的理解 “函數節流” 。
五、函數節流的使用場景
到此爲止,相信各位應該對函數節流有了一個比較詳細的瞭解,那函數節流一般用在什麼情況之下呢?
- 懶加載、滾動加載、加載更多或監聽滾動條位置;
- 百度搜索框,搜索聯想功能;
- 防止高頻點擊提交,防止表單重複提交;
目前遇到過的使用場景就是這些了,不過理解了原理,小夥伴可以把它運用在需要用到它的任何場合,提高代碼質量。
總結
使用“函數節流”的主要目的,是爲了優化程序性能,提高用戶體驗,不過最主要的爲了節約計算機資源,推薦在合適的場合使用它,才能達到它應有的效果,切忌濫用哦!