//@ts-check /** * * Creates a throttled function that only invokes the provided function at most * once per within a given number of milliseconds. * * @template {(...args: any) => any } F * @template {ReturnType} R * @template {Parameters} P * @param {F} func * @param {number} [firingRateMs] Firing rate (50ms by default) */ export const throttle = (func, firingRateMs = 50) => { /** @type {R} */ let lastResult; /** @type {number} */ let last = 0; /** @type {null|P} */ let funcArguments; /** @type {number} */ let timeoutID = 0; const call = () => { timeoutID = 0; last = +new Date(); lastResult = func.apply(null, funcArguments); funcArguments = null; }; /*** * @param {P} args */ const throttled = (...args) => { funcArguments = args; const delta = new Date().getTime() - last; if (!timeoutID) if (delta >= firingRateMs) { call(); } else { timeoutID = setTimeout(call, firingRateMs - delta); } return lastResult; }; return throttled; }; export default throttle