Skip to content

Instantly share code, notes, and snippets.

@Borvik
Created July 18, 2024 10:44
Show Gist options
  • Save Borvik/1da109747c0da537f62da9ebc670a820 to your computer and use it in GitHub Desktop.
Save Borvik/1da109747c0da537f62da9ebc670a820 to your computer and use it in GitHub Desktop.
POC: Leading cached network debounce
/*
This proof-of-concept is to demonstrate how someone might make debounced network requests
where _each_ request returns a value - rather than just the "bounced" calls getting ignored
Essential concept - while network request is in progress, more requests for the exact same
data are "attached" to the original request and all would then complete at the same time.
*/
// mockup of the real network get function (redis, http, db, etc...)
async function realGetData(key: string) {
await new Promise(resolve => setTimeout(resolve, 2500));
return `the_data:${key}`;
}
// stores a map of currently running "get" requests and the promise to the result
const dataMap: Map<string, Promise<string>> = new Map();
// actual get function to call - `count` is there to demonstrate that the value gotten might be from a different call
async function getData(key: string, count: number) {
// first check if there is a request underway
let result = dataMap.get(key);
if (typeof result !== 'undefined') {
// there was - so return that
return result;
}
// get the new request started - while the `.then` is necessary (to cleanup the map), the part of the `count` is not
// we aren't awaiting it here, so it immediately jumps to line 35
result = realGetData(key).then(result => {
dataMap.delete(key);
return result + `:${count}`;
});
// store the request so it can be "debounced"
dataMap.set(key, result);
// return the promise like normal
return result;
}
// this just shows the concept in action
let counter = 0;
setInterval(() => {
if (counter < 5) {
let now = counter;
console.log('GET THE DATA:', now);
getData('some', now).then(result => console.log('DATA RESULT:', { now, result }));
counter++;
}
process.exit();
}, 1000);
/*
Expected output
----------------
GET THE DATA: 0
GET THE DATA: 1
GET THE DATA: 2
DATA RESULT: { now: 0, result: 'the_data:some:0' }
DATA RESULT: { now: 1, result: 'the_data:some:0' }
DATA RESULT: { now: 2, result: 'the_data:some:0' }
GET THE DATA: 3
GET THE DATA: 4
DATA RESULT: { now: 3, result: 'the_data:some:3' }
DATA RESULT: { now: 4, result: 'the_data:some:3' }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment