Throttle a function to a fixed rate
JavaScript
// Throttle: allow one call per `wait` ms and keep the latest arguments.
function throttle(fn, wait, { leading = true, trailing = true } = {}) {
let last = 0;
let timer = null;
let pending = null;
function invoke(args) {
last = Date.now();
fn.apply(null, args);
}
function throttled(...args) {
const elapsed = Date.now() - last;
if (leading && elapsed >= wait) return invoke(args);
if (!trailing) return;
pending = args;
if (timer) return;
timer = setTimeout(() => {
timer = null;
const latest = pending;
pending = null;
if (latest) invoke(latest);
}, Math.max(0, wait - elapsed));
}
throttled.cancel = () => {
clearTimeout(timer);
timer = null;
pending = null;
last = 0;
};
return throttled;
}
const log = throttle((value) => console.log('position', value), 100);
log(1); log(2); setTimeout(() => log(3), 250); // 1, then 2 at ~100 ms, then 3