Skip to content

Instantly share code, notes, and snippets.

@angrykoala
Created May 25, 2023 16:21
Show Gist options
  • Save angrykoala/7565deb5cc3ef8d557776d472d99e1e3 to your computer and use it in GitHub Desktop.
Save angrykoala/7565deb5cc3ef8d557776d472d99e1e3 to your computer and use it in GitHub Desktop.
A promise which execution is deferred until awaited
/** Defers an execution until a promise is awaited */
class DeferredPromise<T = void> extends Promise<T> {
private executor: () => Promise<T>;
private resultPromise: Promise<T> | undefined; // Memoize the promise, to avoid executing the executor twice if awaited twice
constructor(executor: () => Promise<T>) {
super(() => {
// Dummy callback to make Promise happy
});
this.executor = executor;
}
// Overrides Promise's then, so it executes the executor when the promise is awaited.
public then<TResult1 = T, TResult2 = never>(
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
): Promise<TResult1 | TResult2> {
if (!this.resultPromise) {
this.resultPromise = this.executor();
}
return this.resultPromise.then(onfulfilled, onrejected);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment