> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/val/func/kind/higher/decorator/debounce-vs.-throttle.md).

# debounce vs. throttle

[JS](/web/js.md) ⟩ [technique](/web/js/tech.md) ⟩ [decorator](/web/js/val/func/kind/higher/decorator.md) ⟩ debounce vs. throttle

{% hint style="success" %}

* [debounce(f, s)](/web/js/val/func/kind/higher/decorator/debounce-f-s.md) ：\
  (you have to <mark style="color:red;">**pause long enough**</mark>) to run it <mark style="color:yellow;">**once**</mark> at the <mark style="color:red;">**end**</mark> of the “<mark style="color:yellow;">**cooldown**</mark>” period. (good for <mark style="color:yellow;">**processing the**</mark>**&#x20;**<mark style="color:orange;">**final**</mark> <mark style="color:orange;">**input**</mark>)
* [throttle(f, s)](/web/js/val/func/kind/higher/decorator/throttle-f-s.md)： \
  runs it at the <mark style="color:red;">**start**</mark> of the “<mark style="color:yellow;">**cooldown**</mark>” period, further <mark style="color:yellow;">**calls**</mark> during the "cooldown" period are <mark style="color:yellow;">**all**</mark>**&#x20;**<mark style="color:red;">**ignored**</mark>**&#x20;**<mark style="color:yellow;">**except**</mark>**&#x20;**<mark style="color:red;">**the last**</mark>. (good for <mark style="color:orange;">**regular updates**</mark> that <mark style="color:yellow;">**shouldn’t be very often**</mark>)
  {% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="info" %}
[debounce(f, s)](/web/js/val/func/kind/higher/decorator/debounce-f-s.md)&#x20;

相對來說比較單純，沒什麼冷不冷卻的問題，它被呼叫時只做一件事，就是：

* 取消「舊鬧種」（如果有的話）
* 並「設定新鬧鐘」（時間到，即執行該呼叫）

換句話說，不管呼叫多少次，只有「<mark style="color:yellow;">**最後一次有撐過鬧鐘等待時間**</mark>」的呼叫，才會真正觸發鬧鐘，真正執行。也就是要有「<mark style="color:yellow;">**一段時間以上的停頓**</mark>」(s 秒)，動作才會執行❗️
{% endhint %}

{% hint style="warning" %}
呼叫 [throttle(f, s)](/web/js/val/func/kind/higher/decorator/throttle-f-s.md) ​時，

* 如果沒有在「冷卻模式」內：
  * ① 立即進入「冷卻模式」("cooldown" mode)
  * ② 將呼叫傳給 <mark style="color:blue;">`f`</mark> 執行 (forward call to <mark style="color:blue;">`f`</mark>)。
  * ③ 同時「設定鬧鐘」，等「冷卻模式」一結束就：
    * ⑤ 切回「待機模式」("idle" mode)
    * ⑥ 檢查有無「保存的呼叫」(saved call)
      * &#x20;狀況一：如果有，就：
        * ⑦ 送出「保存的呼叫」(send saved call)\
          ( 進入「冷卻時期」、執行 f、「設定鬧鐘」)\
          (⭐️ 注意：是送給 "<mark style="color:blue;">`wrapper`</mark>"，不是 <mark style="color:blue;">`f`</mark>❗️)
        * &#x20;⑧ 清除「保存的呼叫」(clear saved call)
      * 狀況二：沒有，則不做任何事。
* 若在「冷卻模式」內收到新的呼叫：
  * ④  新的呼叫會被「保存」起來，但不執行。\
    (只有「最後一個」呼叫會被保存)

換句話說：

* 雖然呼叫會被執行，但「<mark style="color:yellow;">**接續太快的呼叫**</mark>」會被<mark style="color:red;">**忽略**</mark>，在「<mark style="color:yellow;">**每**</mark>**&#x20;**<mark style="color:blue;">**s**</mark>**&#x20;**<mark style="color:yellow;">**秒內最多只會執行一次**</mark>」，從而達到「<mark style="color:orange;">**節流**</mark>」 (<mark style="color:yellow;">**throttle**</mark>) 的目的❗️
  {% endhint %}
  {% endtab %}

{% tab title="🗺️  throttle" %} <img src="https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2F6uBdzRHIbQiT5mzkuLOv%2Fthrottle.timeline.svg?alt=media&amp;token=dd9f9dec-2230-435c-8ce6-085ee838429b" alt="timeline/states of a throttled function" class="gitbook-drawing">

<img src="https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2FrmFQ1sBVTAyE3jTanSY2%2Fthrottle.timer.view.svg?alt=media&amp;token=b6c049cd-9c50-417e-bb8a-42d089473be2" alt="throttle: timer view" class="gitbook-drawing">
{% endtab %}

{% tab title="📗 參考" %}

* [ ] JS.info ⟩ [Decorators and forwarding, call/apply](https://javascript.info/call-apply-decorators) ⭐️
  {% endtab %}
  {% endtabs %}
