日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

白话debounce和throttle

發(fā)布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 白话debounce和throttle 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

遇到的問題

在開發(fā)過程中會遇到頻率很高的事件或者連續(xù)的事件,如果不進(jìn)行性能的優(yōu)化,就可能會出現(xiàn)頁面卡頓的現(xiàn)象,比如:

  • 鼠標(biāo)事件:mousemove(拖曳)/mouseover(劃過)/mouseWheel(滾屏)
  • 鍵盤事件:keypress(基于ajax的用戶名唯一性校驗)/keyup(文本輸入檢驗、自動完成)/keydown(游戲中的射擊)
  • window的resize/scroll事件(DOM元素動態(tài)定位)
  • 為了解決這類問題,常常使用的方法就是throttle(節(jié)流)debounce(去抖)。throttle(節(jié)流)和debounce(去抖)都是用來控制某個函數(shù)在一定時間內(nèi)執(zhí)行多少次的解決方案,兩者相似而又不同。

    下面就具體的看看兩者的相似和區(qū)別。

    認(rèn)識throttle和debounce

    throttle和debounce的作用就是確認(rèn)事件執(zhí)行的方式和時機,以前總是不太清楚兩者的區(qū)別,容易把二者弄混。

    下面就通過兩個簡單的場景描述一下debounce和throttle,以后想到這兩個場景就不會再弄混了:

    debounce 假設(shè)你正在乘電梯上樓,當(dāng)電梯門關(guān)閉之前發(fā)現(xiàn)有人也要乘電梯,禮貌起見,你會按下開門開關(guān),然后等他進(jìn)電梯; 如果在電梯門關(guān)閉之前,又有人來了,你會繼續(xù)開門; 這樣一直進(jìn)行下去,你可能需要等待幾分鐘,最終沒人進(jìn)電梯了,才會關(guān)閉電梯門,然后上樓。

    所以debounce的作用是,當(dāng)調(diào)用動作觸發(fā)一段時間后,才會執(zhí)行該動作,若在這段時間間隔內(nèi)又調(diào)用此動作則將重新計算時間間隔

    throttle 假設(shè)你正在乘電梯上樓,當(dāng)電梯門關(guān)閉之前發(fā)現(xiàn)有人也要乘電梯,禮貌起見,你會按下開門開關(guān),然后等他進(jìn)電梯; 但是,你是個沒耐心的人,你最多只會等待電梯停留一分鐘; 在這一分鐘內(nèi),你會開門讓別人進(jìn)來,但是過了一分鐘之后,你就會關(guān)門,讓電梯上樓。

    所以throttle的作用是,預(yù)先設(shè)定一個執(zhí)行周期,當(dāng)調(diào)用動作的時刻大于等于執(zhí)行周期則執(zhí)行該動作,然后進(jìn)入下一個新的時間周期

    簡單實現(xiàn)

    有了上面的了解,就可以去實現(xiàn)簡單debounce和throttle了。

    debounce實現(xiàn)

    首先來看看debounce的實現(xiàn),根據(jù)前面對debounce的描述:

  • debounce函數(shù)會通過閉包維護(hù)一個timer
  • 當(dāng)同一action在delay的時間間隔內(nèi)再次觸發(fā),則清理timer,然后重新設(shè)置timer
  • 可以在Chrome中運行下面的代碼,看看debounce的效果,代碼Github鏈接:

    var debounce = function(action, delay) {var timer = null; return function() { var self = this, args = arguments; clearTimeout(timer); timer = setTimeout(function() { action.apply(self, args) }, delay); } } // example function resizeHandler() { console.log("resize"); } window.onresize = debounce(resizeHandler, 300);

    throttle實現(xiàn)

    throttle跟debounce的最大不同就是,throttle會有一個閥值,當(dāng)?shù)竭_(dá)閥值的時候action必定會執(zhí)行一次。

    所以throttle的實現(xiàn)可以基于前面的debounce的實現(xiàn),只需要加上一個閥值,代碼Github鏈接:

    var throttleV1 = function(action, delay, mustRunDelay) {var timer = null, startTime; return function() { var self = this, args = arguments, currTime = new Date(); clearTimeout(timer); if(!startTime) { startTime = currTime; } if(currTime - startTime >= mustRunDelay) { action.apply(self, args); startTime = currTime; } else { timer = setTimeout(function() { action.apply(self, args); }, delay); } }; };

    其實,對于上面的實現(xiàn)可以進(jìn)心簡化,只是通過閉包維護(hù)一個開始的時間:

    var throttleV2 = function(action, delay){var statTime = 0; return function() { var currTime = +new Date(); if (currTime - statTime > delay) { action.apply(this, arguments); statTime = currTime ; } } } // example function resizeHandler() { console.log("resize"); } window.onresize = throttleV2(resizeHandler, 300);

    總結(jié)

    通過前面的介紹,應(yīng)該對debounce和throttle有一個直觀的認(rèn)識了:

    • debounce:把觸發(fā)非常頻繁的事件合并成一次執(zhí)行
    • throttle:設(shè)置一個閥值,在閥值內(nèi),把觸發(fā)的事件合并成一次執(zhí)行;當(dāng)?shù)竭_(dá)閥值,必定執(zhí)行一次事件

    了解了throttle和debounce之后,下面看看他們的常用場景:

    debounce

    • 對于鍵盤事件,當(dāng)用戶輸入比較頻繁的時候,可以通過debounce合并鍵盤事件處理
    • 對于ajax請求的情況,例如當(dāng)頁面下拉超過一定返回就通過ajax請求新的頁面內(nèi)容,這時候可以通過debounce合并ajax請求事件

    throttle

    • 對于鍵盤事件,當(dāng)用戶輸入非常頻繁,但是我們又必須要在一定時間內(nèi)(閥值)內(nèi)執(zhí)行處理函數(shù)的時候,就可以使用throttle

      • 例如,一些網(wǎng)頁游戲的鍵盤事件
    • 對于鼠標(biāo)移動和窗口滾動,鼠標(biāo)的移動和窗口的滾動會帶來大量的事件,但是在一段時間內(nèi)又必須看到頁面的效果

      • 例如對于可以拖動的div,如果使用debounce,那么div會在拖動停止后一下子跳到目標(biāo)位置;這時就需要使用throttle

    轉(zhuǎn)載于:https://www.cnblogs.com/gluncle/p/9945009.html

    總結(jié)

    以上是生活随笔為你收集整理的白话debounce和throttle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。