目錄二、 節流
有這樣一種情況,想象有乙個表單,點選提交按鈕就傳送請求給伺服器。如果使用者在很短的時間間隔內「手抖」點選了多次,又或者是惡意點選,那麼就將傳送多個請求。 該行為將造成伺服器額外的不必要負載。
所謂防抖,實際上就是是處理這種常見的情況的描述。
submit
該段**,當點選submit按鈕的時候,將會觸發onclick事件一次,多次點選,將多次觸發。
為了解決該問題,核心就是使用乙個settimeout 定時器。
submit
這就是乙個基本防抖的實現。如果不容易看明白,下面我們詳細的分析。
為了便於理解,我們先將第7行注釋掉:
const btn = document.queryselector('button');
let timer = null;
btn.onclick = function()
我們定義了乙個全域性變數timer
用於預存settimeout
例項物件,初始值設定為null
。
當onclick
函式被觸發一次時,函式體內timer定時器立即被觸發,將在500毫秒後執行console列印。
如果點選多次,由於settimeout的非同步執行特點,將會開啟多個settimeout 例項,各自的延時到500毫秒之後,依次執行列印。
列印完畢後,timer被銷毀。
現在取消第7行注釋:
const btn = document.queryselector('button');
let timer = null;
btn.onclick = function()
我們以兩次間隔較短的點選為例:第一次點選時,timer為null,cleartimeout(timer)即cleartimeout(null), 這並不影響,不會報錯。 然後開啟了乙個settimeout定時器a,等候500毫秒後執行。 但是,如果在間隔小於500毫秒內,第二次點選,定時器a 還在等候,但是我觸發onclick事件時,直接就將定時器timer,即定時器a清除了,所以定時器a內的列印就不會執行,然後開啟乙個新的定時器b。
就這樣,只要我在小於定時器中定義的時間間隔內重複點選,那麼之前的定時器都將被清除掉。始終執行最後乙個定時器。最大的外徵特點就是,狂點按鈕,但是只有鬆手的時候,最後那一次點選有效。
以上,就是所謂的防抖,並不複雜,但是確實很巧妙。
防抖的應用場景主要是為了不讓一些行為頻繁觸發
同樣是為了避免頻繁觸發某個行為,還有一種實現方式,它和防抖的實現有所區別。
關於節流,我想到了乙個絕佳的例子。 就是技能cd。 如果玩過無限火力小黃毛就更容易理解了。q鍵恨不得不鬆開。
有時候,我們希望我們能夠多次觸發某個行為,但是又不能讓他沒有間隔的瘋狂觸發。 那麼這時候的解決方案,就叫做節流。
我希望我在技能cd好了的時候,立即可以使用該技能。 但是總不能讓你無限光速連q吧, 那叫bug。
實際上,節流的實現也很簡單。
submit
簡單的來講,就是加上乙個自動「開關」。
我們預先定義了乙個全域性的變數trigger;當點選submit 按鈕,onclick 被觸發。 然後依據trigger的值,來決定是否繼續執行if
then塊中的邏輯。
首次點選,由於trigger的預定義值為true,所以if
then 塊中的邏輯必定會被執行。但是一旦進入塊,立即將trigger的值改作false (這樣就實現了關閉了if的塊邏輯執行的「開關」。),執行一次任務後,我們通過settimeout 埋乙個定時器,1秒後執行,其任務就是將「開關」再次開啟。 那麼第二次點選submit按鈕的時候, 如果定時器超過了一秒,「開關」被開啟,即trigger為true,才會執行,if
then 邏輯塊中的任務。 否則就得等待「開關」被開啟。
這樣,通過「開關」的控制,就能實現,即便連續點選,但是也只能按照指定的間隔時間去觸發任務。 這就是節流。
節流的應用場景是,依然需要讓它頻繁觸發,但是要有規則的頻繁觸發。 不能讓它無縫連續觸發。
什麼是防抖和節流?
雖然二者都有延遲當前動作的反饋,但是防抖的延遲時間是確定的,延遲週期內如果有新動作進入,舊的動作將會被取消。而節流是提前設定了乙個閥門,只有當閥門開啟的時候,該動作才有機會執行。如果閥門是關閉的,那這個動作就不會進入執行區。個人理解防抖是後置的處理高頻事件方式,而節流是前置處理。防抖機制隱含了乙個優...
防抖和節流
在前端開發過程中,我們經常需要繫結一些持續觸發事件,如 resize scroll mousemove等等,但有些時候我們並不希望在事件持續觸發的過程中那麼頻繁的去執行函式。通常這種情況下,我們怎麼去解決呢?一般來講,防抖和節流是比較好的解決方案。一 函式的防抖 1 什麼是函式防抖 函式防抖 deb...
防抖和節流
防抖和節流的作用都是防止函式多次呼叫。區別在於,假設乙個使用者一直觸發這個函式,且每次觸發函式的間隔小於設定的時間,防抖的情況下只會呼叫一次,而節流的情況會每隔一定時間呼叫一次函式。1.防抖 函式防抖 debounce n秒內函式只會執行一次,如果n秒內高頻事件再次被觸發,則重新計算時間。如下例,對...