47 lines
1.1 KiB
JavaScript
47 lines
1.1 KiB
JavaScript
|
/**
|
||
|
* Wrap an async function to cache its result.
|
||
|
*
|
||
|
* On first call of the wrapped function, the result will be stored and further
|
||
|
* calls will directly return this cached value (always inside a promise).
|
||
|
*
|
||
|
* A `.noCache` method is provided to force getting a fresh value.
|
||
|
*
|
||
|
* Each cache value is scoped to the array of arguments that yielded it
|
||
|
* (comparison done using its JSON representation).
|
||
|
*
|
||
|
* @param fun Function to wrap.
|
||
|
* @return Wrapped function.
|
||
|
*/
|
||
|
const makeCached = fun =>
|
||
|
{
|
||
|
const cachedResults = new Map();
|
||
|
|
||
|
const noCache = async (...args) =>
|
||
|
{
|
||
|
const result = await fun(...args);
|
||
|
cachedResults.set(JSON.stringify(args), result);
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
const withCache = async (...args) =>
|
||
|
{
|
||
|
const key = JSON.stringify(args);
|
||
|
|
||
|
if (cachedResults.has(key))
|
||
|
{
|
||
|
return cachedResults.get(key);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
const result = await fun(...args);
|
||
|
cachedResults.set(key, result);
|
||
|
return result;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
withCache.noCache = noCache;
|
||
|
return withCache;
|
||
|
};
|
||
|
|
||
|
exports.makeCached = makeCached;
|