Skip to content

Instantly share code, notes, and snippets.

@rolangom
Last active September 3, 2020 13:10
Show Gist options
  • Save rolangom/150758e5a14be557ed492003a1b4685c to your computer and use it in GitHub Desktop.
Save rolangom/150758e5a14be557ed492003a1b4685c to your computer and use it in GitHub Desktop.
Centralized fetcher function that caches the response.
const _sessionStore = {};
const sessionStore = {
getItem: (id) => _sessionStore[id] || null,
setItem: (id, value) => _sessionStore[id] = value,
clear: () => _sessionStore = {},
}
/**
*
* @template T
* @param {number} ms
* @param {T} value
* @returns {Promise<T>}
*/
const sleep = (ms, value) => new Promise(resolve => setTimeout(resolve, ms, value));
const LOADING_TAG = '%%LOADING%%';
/**
* @async
* @template T
* @param {string} id
* @param {() => Promise<T>} fn
* @param {{ defaultTimeout: number }} config
* @returns {T}
*/
async function centralFetcher(id, fn, config = { defaultTimeout: 100, defaultStorage: sessionStore }) {
const localValue = config.defaultStorage.getItem(id);
if (localValue === LOADING_TAG) {
await sleep(config.defaultTimeout);
return centralFetcher(id, fn);
}
if (localValue === null) {
config.defaultStorage.setItem(id, LOADING_TAG);
const value = await fn();
config.defaultStorage.setItem(id, value);
return value;
}
return localValue;
}
async function run() {
try {
const values = await Promise.all([
centralFetcher('a', () => sleep(100, 1)),
centralFetcher('b', () => sleep(200, 2)),
centralFetcher('a', () => sleep(300, 3)),
centralFetcher('b', () => sleep(500, 4)),
// centralFetcher('c', () => reject(500, Error('Ha ocurrido un error'))),
]);
console.log('values', values);
} catch (err) {
console.error("Run err", err.message);
}
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment