class CachedRun { /** * Constructor for the class. Receives a period and a request function to run. * * @param {number} period - Number of millis to keep the cache. * @param {function} request - Function that returns the requested value. * @param {function} [process] - Run data from the request through this function before caching. * @param {function} [allways] - Run data through this allways at the end of the pipeline. */ constructor(period, request, process, allways){ this.period = period; this.request = request; this.postProcess = process || (el=>el); this.allwaysRun = allways || (el=>el); this.lastCall = 0; this.self = this; } /** * Run the request function and the postprocess function (if there's one defined). * * @return {Promise} Promise with the requested values allready processed. */ getFreshResults(){ return Promise .resolve(this.request()) .then(res => this.postProcess(res)); } /** * Stores cache and manages timer. * * @param {Object} [results] - Results from the request and further postprocess. * @param {Promise} Promise with the cached results processed. */ cacheResults(results){ if(results) { this.cache = results; this.lastCall = +new Date(); } return Promise .resolve(this.cache) .then(data => this.allwaysRun(data)); } /** * Run the pipeline according to the configuration. * * @return {Promise} Data run through all the pipeline. */ start(){ return (new Date() - this.lastCall > this.period)? this.getFreshResults().then(res => this.cacheResults(res)) : this.cacheResults(); } }