Skip to content

throttle

スロットル。関数が立て続けに呼ばれたとき、一定の間隔につき多くても一度だけ実行します。最初の呼び出しはすぐに走り(先頭側)、その区間の最後の呼び出しは区間が閉じるときに改めて走る(末尾側)ので、最終的な状態が落ちることはありません。

スクロール、ポインターの移動、ドラッグなど、途中の反応が要る 場面で使ってください。「最後の値だけが問題」(入力しながらの検索、自動保存)なら debounce を使います。

API

throttle(fn, delay?)

パラメーター

パラメーター説明既定値
fnスロットルする関数Function必須
delay最短の間隔(ミリ秒)number300

戻り値

呼び出し元の this と引数を保つ、スロットル済みの関数です。加えて次のものを持ちます。

メンバー説明
cancel()待機中の末尾側の呼び出しを捨てます() => void
pending()末尾側の呼び出しが待機中かどうか() => boolean

使用例

js
import { throttle } from 'ranuts';

const onScroll = throttle(() => update(window.scrollY), 100);
window.addEventListener('scroll', onScroll);

// 後片づけでは、リスナーを外す *だけでなく* 待機中の末尾側の呼び出しも捨てます
window.removeEventListener('scroll', onScroll);
onScroll.cancel();

補足

  1. 先頭側と末尾側:まずすぐに実行し、区間の終わりにもう一度、いちばん新しい引数で実行します。
  2. this と引数 は呼び出し元からそのまま渡されます。
  3. どこでも動きます:素の setTimeout を使うので、Node でも Web Worker でも SSR でも動きます。
  4. throttle() を呼ぶたびに区間は別々です。 ふたつのスロットル済み関数が干渉することはありません。
  5. 後片づけでは必ず cancel() を呼んでください。 さもないと、末尾側の呼び出しが壊れた文脈へ発火します。

0.3 で削除しました

generateThrottle() はなくなりました。返されるファクトリーが生む関数は タイマーもタイムスタンプもひとつを共有していた ので、無関係なスロットル済み関数どうしが互いを抑え込んでいました。const g = generateThrottle(); const f = g(fn, delay)throttle(fn, delay) に置き換えてください。

MIT ライセンスのもとで公開されています。