Skip to content

Instantly share code, notes, and snippets.

@dantman
Created February 17, 2021 03:17
Show Gist options
  • Save dantman/f3cba7613c53102cf1a5130d44009e68 to your computer and use it in GitHub Desktop.
Save dantman/f3cba7613c53102cf1a5130d44009e68 to your computer and use it in GitHub Desktop.
A hook that takes a promise and throws it according to the Suspense API
interface PromiseCachePending {
promise: Promise<void>;
}
interface PromiseCacheResolved<T> {
promise: Promise<void>;
result: T;
}
interface PromiseCacheError {
promise: Promise<void>;
error: any;
}
type PromiseCache<T> =
| PromiseCachePending
| PromiseCacheResolved<T>
| PromiseCacheError;
const PROMISE_CACHE = new WeakMap<Promise<any>, PromiseCache<any>>();
/**
* This is a hook that takes a promise and throws it according to the Suspense API
*
* @note This is a bit of a hack since this API is really low level and the full version of Suspense isn't released yet
*/
export default function awaitPromise<T>(promise: Promise<T>): T {
let promiseCache: PromiseCache<T> | undefined = PROMISE_CACHE.get(promise);
if (promiseCache) {
if ('error' in promiseCache) {
throw promiseCache.error;
}
if ('result' in promiseCache) {
return promiseCache.result;
}
throw promiseCache.promise;
}
promiseCache = {
promise: promise
.then((result) => {
Object.assign(promiseCache, {
result,
});
})
.catch((error) => {
Object.assign(promiseCache, {
error,
});
}),
};
PROMISE_CACHE.set(promise, promiseCache);
throw promiseCache.promise;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment