import {throttle, ThrottleSettings} from 'lodash'; type IHandler = (items: T) => void; export function throttleAndCombine( fn: IHandler, combine: (a: T, b: T) => T, wait: number, options?: ThrottleSettings, ): IHandler { let queue: T | null = null; const callbackThrottled = throttle( () => { fn(queue); queue = null; }, wait, options, ); return (items: T) => { if (queue == null) { queue = items; } else { queue = combine(queue, items); } callbackThrottled(); }; } export function throttleAndCombineArray( fn: IHandler>, wait: number, options?: ThrottleSettings, ) { return throttleAndCombine( fn, (a, b) => a.concat(b), wait, options, ); } /** * When throttled function is called more frequently than specified via `wait` param, * it keeps the set in memory and after the wait threshold "times out" * it then invokes the handler function with a combined set which has items from previous calls * where due to throttling, the handler wasn't called. */ export function throttleAndCombineSet( fn: IHandler>, wait: number, options?: ThrottleSettings, ) { return throttleAndCombine( fn, (a, b) => { var result = new Set(); a.forEach((item) => { result.add(item); }); b.forEach((item) => { result.add(item); }); return result; }, wait, options, ); }