上次在知乎上看到了一篇文章,在此自己靠著記憶以及以前的筆記 回憶下開發流程。如有不足,歡迎指正 。以此共勉!!
前記:
記得有次專案開發中,我們老大說 登陸按鈕如果我一直點選,你的login介面請求了多次,這個影響效能,不行吧。你處理下 明天爭取解決了 。因為我們做的是產品 所以工作不急 你懂的。。。 後面我在想 既然不讓他一直點選登陸 那我能不能 定一個flage 初始化false 點選登陸的時候設定為true 當介面返回資料後 賦值為false 並且flage ==true的時候 設定登陸按鈕 readonly 然後就著手開發了 親測還行 嘿嘿 。 然而 有一天 我做了另一個功能 給一個div設定可以拖拽大小的功能。當大小變化的時候 觸發一個初始化echarts的函式。臥槽 開發的時候遇到一個大問題。瀏覽器echarts初始化時候圖形一直抖動。最後console 一下 初始化方法觸發了很多次 。。。。。妹的 這怎麼辦。當時是個前端小白 (今天也是個 妹的)然後問我們老大 自己解決不了 結果被他說了一頓 ‘不會問度娘 娘不行就去問哥(google )’ 好吧 當時我都不知道在網上該怎麼表達遇到的這種情況。然後亂搜尋啊‘怎樣約束一個方法不觸發多次?’無意間看到一句話‘Debounce 和 Throttle 的原理及實現’點開一看 哎呦 老天開眼啊 這不是我要的東西嗎 !?
正題:
專門上網上翻譯了下
防反跳 也就是說在一定時間裡 只能執行一個方法 如果觸發多個方法 那麼多個方法會合併成一個 結果只執行一個 嗯 是這樣的。那麼肯定要向setTimeout函式封裝的一樣 setTimeout(fn,timeout)這個模仿它應該是 debouce(fn,timeout) 那麼這個fn應該怎麼寫呢?
那就直接上程式碼吧:
/*fn 執行的方法timeout 延遲的時間
*/function debouce(fn, timeout) {var time;return function() {var _this = this;var args = arguments;clearTimeout(timer);time = setTimeout(() => {fn.apply(_this, args);}, timeout);}}
複製程式碼
解釋一下:
呼叫debouce 入參兩個變數,結果 返回一個方法 。通過程式可以知道: 當連續觸發四次方法的時候,返回四個方法 因為閉包的原因 程式執行完後並不會回收記憶體 那麼time 還是被定義的 存在的。這時候執行第一個方法 var time; 而time本來就是undefined , clearTimeout(timer); 沒個卵用 然後接著往下走,time被賦值 。當執行第二個方法的時候,clearTimeout(timer); 結果time又被清空了 。然後走第三個方法 clearTimeout(timer); 也沒個卵用 因為第二個方法已經清空了它。往下走 time被賦值。當第四個方法執行的時候,clearTimeout(timer)清空第三個方法賦的值 然後接著走 第四次time被重新賦值。整個下來 time是在第四次方法呼叫的時候賦的值才沒有被清空。然後 timeout時間到了 制動執行該fn.
且只執行一次。
總結:關鍵是對閉包的理解。
有個高大上的名字:函式節流 。 這個起名字的真是個大神
節流:即函式以勻速的頻率來執行
閒話少數 直接上程式碼:
function throttle(fn, timeout = 250) {var last;var timer;
return function() {var _this = this; //上下文環境var args = arguments; //var now = +new Date(); //獲取當前時間戳
if (last && last + timeout > now) { //last + threshhold > now 說明延遲時間timeout 還沒到clearTimeout(timer);timer = setTimeout(function() {last = now;fn.apply(_this, args)}, timeout)} else {last = now;fn.apply(_this, args);}}}
複製程式碼
總的來說 就是比debouce 多了個時間範圍判斷 說明已在程式碼註釋上。
總結:
debounce 強制函式在某段時間內只執行一次,throttle 強制函式以固定的速率執行。
throttle 常用的場景是限制 resize 和 scroll 的觸發頻率。而其他解決觸發多次方法可以使用debounce。如mouseover mouvemove keyup 等。
備註:文章有些是以前的學習筆記,直接拷貝上來的。侵刪!