Schedule code execution using setTimeout and setInterval, and rate-limit handlers using debounce and throttle patterns.
setTimeout and setInterval.setTimeout or setInterval to cancel execution when conditions change.requestAnimationFrame over setInterval when creating web animations to match the display refresh rate.setInterval loop creates memory leaks that persist throughout application life.setTimeoutSchedules a single callback execution after a specified millisecond delay.
setTimeout(() => {
console.log("Runs after 1 second");
}, 1000);Timer cancellationCancels a scheduled setTimeout callback before execution using its timer ID.
const id = setTimeout(() => console.log("done"), 5000);
clearTimeout(id);Forwarding argumentsPasses extra arguments directly into the timer callback function handler.
setTimeout(u => console.log(u), 1000, "Alice");Zero delayQueues a callback at the end of the current execution stack immediately.
console.log("first");
setTimeout(() => console.log("third"), 0);
console.log("second");setIntervalSchedules repeated callback execution on a fixed time interval loop.
const id = setInterval(() => {
console.log("tick");
}, 1000);Self-clearing intervalStops a repeating interval internally once a counter threshold is met.
let count = 0;
const id = setInterval(() => {
count++;
if (count >= 5) clearInterval(id);
}, 1000);Poller cleanupsClears active poll intervals during cleanups to prevent resource leaks.
function poll() {
const id = setInterval(fetchData, 5000);
return () => clearInterval(id); // clean
}Recursive timeoutChains setTimeouts recursively to ensure steady spacing between variable runs.
function poll() {
doWork();
setTimeout(poll, 1000);
}
poll();Main thread blocksTimers await thread clearance, causing late execution if synchronous blocks run.
setTimeout(() => console.log("late"), 0);
while (Date.now() < start + 200) {} // blockSequential queueingLong synchronous execution blocks delay all queued callbacks concurrently.
setTimeout(() => console.log("A"), 10);
setTimeout(() => console.log("B"), 20);
// delayed together if thread is busyMacrotask queueingTimers run as macrotasks, resolving after synchronous code and microtasks.
console.log("1");
setTimeout(() => console.log("3"), 0);
Promise.resolve().then(() => console.log("2"));Debounce helperDelays function execution, resetting the timer on each new invocation.
function debounce(fn, delay) {
let id;
return (...args) => {
clearTimeout(id);
id = setTimeout(() => fn(...args), delay);
};
}Input searchLimits API fetch queries by triggering only after typing pauses.
const search = debounce(query => fetch(query), 300);
input.addEventListener("input", e => {
search(e.target.value);
});Throttle helperExecutes a function at most once per fixed time interval window.
function throttle(fn, limit) {
let wait = false;
return (...args) => {
if (wait) return;
fn(...args);
wait = true;
setTimeout(() => { wait = false; }, limit);
};
}Scroll trackingProtects browser scroll listeners from triggering expensive paint redraws.
const logScroll = throttle(() => updateUI(), 200);
window.addEventListener("scroll", logScroll);rAF animation loopSchedules callbacks right before the browser repaints active screen elements.
function animate() {
moveElement();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);Animation stopTerminates a requestAnimationFrame animation loop using the returned ID.
const id = requestAnimationFrame(animate);
cancelAnimationFrame(id);Scroll syncSynchronizes visual adjustments directly with browser repaint refresh frames.
let ticking = false;
window.addEventListener("scroll", () => {
if (!ticking) {
requestAnimationFrame(() => {
updateScroll();
ticking = false;
});
ticking = true;
}
});JavaScript runs on a single thread. The event loop cannot run timer callbacks until the call stack is empty. Long synchronous tasks block the queue and delay timer execution.
Debouncing waits for a pause in events before running a function once. Throttling limits execution to at most once per fixed time interval. Use debouncing for search input and throttling for scrolling.
No, setTimeout callbacks remove themselves from the event queue automatically after running. You only need to call clearTimeout to cancel a pending timer before it executes.
The requestAnimationFrame method coordinates callbacks with display refresh rates, creating smoother motion. It also pauses automatically when browser tabs become inactive. This saves battery and processor power.
No, the browser prevents concurrent execution by waiting for the thread to clear. However, callbacks can queue up and fire rapidly in succession. Use recursive setTimeout for regular spacing instead.
Search Debouncer with Resource Cleanup
Creates a search debouncer that delays query submissions and offers a cleanup method to prevent memory leaks.
function createSearchInput(onSearch) {
let timerId;
function handleInput(event) {
clearTimeout(timerId);
const query = event.target.value;
timerId = setTimeout(() => {
onSearch(query);
}, 300);
}
function destroy() {
clearTimeout(timerId);
}
return { handleInput, destroy };
}Implement debouncing to rate-limit expensive api requests, and always clean up timers to prevent application memory leaks.