Skip to content

Instantly share code, notes, and snippets.

@dinigo
Last active December 14, 2017 23:44
Show Gist options
  • Save dinigo/ebe022ae18e715e7312901bf06cbeae9 to your computer and use it in GitHub Desktop.
Save dinigo/ebe022ae18e715e7312901bf06cbeae9 to your computer and use it in GitHub Desktop.
Cache requests instead of firing them to the API

Cached Runner receives a period of time and a request function, and performs all async operations to get the data. If you retry the request in a time shorter than the period it returns the cached result instead.

You can also set a postprocess function and another function that runs every time.

Here you have an example:

const period = 2000;  // ms
const allways = data => +new Date() + ' --> ' + data;  // an allways run function that adds a timestamp
const request = () => Math.random();  // a request function that generates a random number
const process = num => `~(${Math.ceil(num*100)})~`;
const cachedRun = new CachedRun(period, request, process, allways);
cachedRun.start().then(res => console.log(res));
setTimeout(() => cachedRun.start().then(res => console.log(res)),1000);
setTimeout(() => cachedRun.start().then(res => console.log(res)),3000);

Inmediate after invocation request -> process -> cached -> allways -> returned. New timestamp and new random number:

> "1513186989013 --> ~(4)~"

One second after invocation data isn't refreshed since period hasn't expired so: cached -> allways -> returned. New timestamp and cached random number:

> "1513186990016 --> ~(4)~"

Three secons after first invocation cache has expired, so request is rerun: request -> process -> cached -> allways -> returned. New timestamp and new random number:

> "1513186992017 --> ~(90)~"
class CachedRun {
constructor(period, request, postProcess, allwaysRun){
this.period = period;
this.request = request;
this.postProcess = postProcess || (el=>el);
this.allwaysRun = allwaysRun || (el=>el);
this.lastCall = 0;
this.self = this;
}
getFreshResults(){
return Promise
.resolve(this.request())
.then(res => this.postProcess(res));
}
cacheResults(results){
if(results) {
this.cache = results;
this.lastCall = +new Date();
}
return Promise
.resolve(this.cache)
.then(data => this.allwaysRun(data));
}
start(){
return (new Date() - this.lastCall > this.period)?
this.getFreshResults().then(res => this.cacheResults(res)) : this.cacheResults();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment