@wormss/lazy-promise
v1.0.1
Published
lazy promise execution
Downloads
154
Readme
@wormss/lazy-promise
Because sometimes you don't want a promise to run any code until at least something awaits it
npm i @wormss/lazy-promise// Pick your import of choice
import { lazyThenable } from '@wormss/lazy-promise';
import { lazyPromise } from '@wormss/lazy-promise';
import { lazy } from '@wormss/lazy-promise';
async function main() {
const myPromise = lazyThenable(() => {
// some expensive thing maybe
return 'I am lazy';
}); // factory hasn't been called yet..
// .... some more big stuff..
const value = await myPromise; // now factory has been called.
const value2 = await myPromise; // factory is NOT called again — same result reused.
}There is no secret or special sauce to this package. It's just a PromiseLike object that doesn't
call the factory method until something attempts to await (or .then()) it. Once called, the
result is cached — repeated awaits share the same promise without re-invoking the factory.
function lazyThenable<T>(factory: () => T | PromiseLike<T>): PromiseLike<T> {
let promise: Promise<T>;
return {
then<TResult1 = T, TResult2 = never>(
onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>,
onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>,
): PromiseLike<TResult1 | TResult2> {
return (promise ??= Promise.resolve(factory())).then(onfulfilled, onrejected);
},
};
}And for those who think TS is the devil, and just want to copy/paste the end result, then here you go, nice and simples.
function lazyThenable(factory) {
let promise;
return {
then(onfulfilled, onrejected) {
return (promise ??= Promise.resolve(factory())).then(onfulfilled, onrejected);
},
};
}