Created
July 18, 2024 10:44
-
-
Save Borvik/1da109747c0da537f62da9ebc670a820 to your computer and use it in GitHub Desktop.
POC: Leading cached network debounce
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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