Throttle
Source: https://bigfrontend.dev/problem/implement-basic-throttle
// In case of a "storm of events", this executes once every $threshold// For throttle, we will call the function at most once every waitfunction throttle(func, wait) {// Initialize a timer and keep track of lastArgslet timeout = null;let lastArgs = null;// Return a throttled functionreturn function throttled(...args) {// If there is no existing timer, we will call the func alreadyif (!timeout) {func.apply(this, args);} else {// Otherwise, we set the lastArgs for when the cooldown is overlastArgs = args;}// In a later functionconst later = () => {// If there are lastArgs, we will call the func, reset last args, and start the cooldown timer againif (lastArgs) {func.apply(this, lastArgs);lastArgs = null;timeout = setTimeout(later, wait)} else {// Otherwise, reset the timeouttimeout = null;}}// Assign timeout to setTimeout if there is no timeoutif (!timeout) {timeout = setTimeout(later, wait);}}}const throttledFunc = throttle((message) => { console.log(`Throttled ${message}`) }, 100);throttledFunc("1");throttledFunc("2");throttledFunc("3");// Should be Throttled 1 (from first call) Throttled 3 (from last call)
Throttle with leading and trailing options
Source: https://bigfrontend.dev/problem/implement-throttle-with-leading-and-trailing-option
// leading=true means to invoke right away// trailing= true means to invoke after the delay// leading=true,trailing=true is basic throttle// leading=false,trailing=false means to do nothingfunction throttle(func, wait, option = {leading: true, trailing: true}) {// Initialize a timer and keep track of lastArgslet timeout = null;let lastArgs = null;// Return a throttled functionreturn function throttled(...args) {// If there is no existing timer and it's leading, we will call the func alreadyif (!timeout && option.leading) {func.apply(this, args);} else {// Otherwise, we set the lastArgs for when the cooldown is overlastArgs = args;}// In a later functionconst later = () => {// If there are lastArgs and it's trailing, we will call the func, reset last args, and start the cooldown timer againif (lastArgs && option.trailing) {func.apply(this, lastArgs);lastArgs = null;timeout = setTimeout(later, wait)} else {// Otherwise, reset the timeouttimeout = null;}}// Assign timeout to setTimeout if there is no timeoutif (!timeout) {timeout = setTimeout(later, wait);}}}