@v4fire/core
Version:
V4Fire core library
61 lines (50 loc) • 1.79 kB
text/typescript
/*!
* V4Fire Core
* https://github.com/V4Fire/Core
*
* Released under the MIT license
* https://github.com/V4Fire/Core/blob/master/LICENSE
*/
import SyncPromise from 'core/prelude/structures/sync-promise';
import type { PromiseLikeP } from 'core/async';
import { weakMemoizeCache, longMemoizeCache } from 'core/promise/sync/const';
/**
* Memorizes the specified promise and converts it to a synchronous promise.
* It means that after the first resolution,
* the promised result will be cached, and the method returns the synchronous version of a promise.
*
* @param keyOrPromise - promise or a promise factory to cache, or a key to cache the promise
* @param promise - promise or a promise factory to cache (if the first argument is a key)
*
* @example
* ```
* memoize(nextTick());
* memoize('core/url/concat', () => import('core/url/concat'));
* ```
*/
export function memoize<T = unknown>(keyOrPromise: unknown | PromiseLikeP<T>, promise?: PromiseLikeP<T>): Promise<T> {
return new SyncPromise((resolve, reject) => {
if (keyOrPromise != null && typeof keyOrPromise === 'object') {
if (weakMemoizeCache.has(keyOrPromise)) {
return resolve(weakMemoizeCache.get(keyOrPromise));
}
} else if (Object.isPrimitive(keyOrPromise) && longMemoizeCache.has(keyOrPromise)) {
return resolve(longMemoizeCache.get(keyOrPromise));
}
let p = promise ?? keyOrPromise;
p = Object.isFunction(p) ? p() : p;
if (!Object.isPromise(p)) {
throw new ReferenceError('A promise to wait is not found');
}
p
.then((val) => {
if (keyOrPromise != null && typeof keyOrPromise === 'object') {
weakMemoizeCache.set(keyOrPromise, val);
} else {
longMemoizeCache.set(keyOrPromise, val);
}
resolve(val);
})
.catch(reject);
});
}