a throttled function blocks the execution of fn, if less than delta_time_ms amount of time has passed since the previous non-rejected call. a rejected caller would receive the THROTTLE_REJECT symbol, instead of the fn function's evaluated value.

the following visual illustration should give you an idea of how a throttled function with delta_time_ms = 1000 would behave.

  • the intersections in the call made axis specifies the time where a call is made to the throttled function.
  • successfully evaluated calls are labeled as resolved (with the legend marker o), and their caller will receive the evaluated value of fn()
  • unsuccessful calls (i.e. rejected) are labeled as rejected (with the legend marker x), and their caller will receive the symbol value THROTTLE_REJECT.
│resolved │  o         o                  o                           
│rejected │  │ x  x x  │ x                │ x x                       
│call made├──┴─┴──┴─┴──┴─┴────────────────┴─┴─┴─────────────────► time
│time     │  0         1         2         3         4         5      
import {
assertEquals as assertEq,
assertLessOrEqual as assertLe,
assertGreaterOrEqual as assertGe,
} from "jsr:@std/assert"

// a function that creates an asynchronous delay of the given number of milliseconds
const sleep = (time_ms: number) => (new Promise((resolve) => (setTimeout(resolve, time_ms))))

const
log_history: Array<[time: number, value: number]> = [],
t0 = performance.now(),
current_time = () => (performance.now() - t0)

// the function that we plan to apply throttling to
const fn = (v: number) => {
log_history.push([current_time(), v])
return v + 100
}

// the throttled version of `fn`, that blocks subsequent calls when they are made under the `delta_time` interval (1000ms here).
const throttled_fn = throttle(1000, fn)

// first call to the `throttled_fn` will be evaluated successfully and immediately
const a = throttled_fn(24)

assertEq(a, 100 + 24)
assertGe(log_history[0][0], 0)
assertLe(log_history[0][0], 100)
assertEq(log_history[0][1], 24)

// subsequent calls to the `throttled_fn` that are made under 1000ms, will be immediately rejected with the symbol value `THROTTLE_REJECT`.
await sleep(200)
const b1 = throttled_fn(37)
const b2 = throttled_fn(42)

assertEq(b1, THROTTLE_REJECT)
assertEq(b2, THROTTLE_REJECT)
assertGe(current_time(), 199)
assertLe(current_time(), 400)

// finally, when 1000ms has passed, `throttled_fn` will permit another successful call
await sleep(800)
const c = throttled_fn(99)

assertEq(c, 100 + 99)
assertGe(log_history[1][0], 999)
assertLe(log_history[1][0], 1300)
assertEq(log_history[1][1], 99)
  • Type Parameters

    • T extends unknown
    • ARGS extends any[]

    Parameters

    • delta_time_ms: number

      the time interval in milliseconds for throttling

    • fn: (...args: ARGS) => T

      the function to be throttled

    Returns (...args: ARGS) => typeof THROTTLE_REJECT | T

    a function (that takes arguments intended for fn) that returns the value of fn if it was not throttled, otherwise a THROTTLE_REJECT symbol is returned.