Hey folks, I’m in the middle of shipping a dashboard where multiple widgets hit the same endpoint, and I’m trying to decide if adding client-side request dedupe + a tiny cache is worth the complexity or just future pain.
const inFlight = new Map<string, Promise<any>>();
const cache = new Map<string, { at: number; data: any }>();
export function fetchOnce(key: string, fn: () => Promise<any>, ttlMs = 5000) {
const hit = cache.get(key);
if (hit && Date.now() - hit.at < ttlMs) return Promise.resolve(hit.data);
const existing = inFlight.get(key);
if (existing) return existing;
const p = fn()
.then((data) => {
cache.set(key, { at: Date.now(), data });
return data;
})
.finally(() => inFlight.delete(key));
inFlight.set(key, p);
return p;
}
Given the failure modes (stale data, memory growth, weird cross-widget coupling), how do you decide when this pattern is a net product win vs keeping it simple and eating the extra requests?