resolveDeferred
Returns a promise's value when it is already known to be resolved, and the promise itself otherwise; plain values pass through.
import { resolveDeferred } from '@salla.sa/twilight-theme-engine/components/common';In plain words
Sometimes you want a value right now if it is already there, and to wait otherwise. resolveDeferred(x) gives back a plain value unchanged. For a promise, it gives back the result if it already knows the promise has resolved, and the promise itself if not.
Signature
function resolveDeferred<T>( promiseOrValue: Promise<T> | T | undefined ): T | Promise<T> | undefined
Try it live
import { resolveDeferred } from '@salla.sa/twilight-theme-engine/components/common';
export function Rating({ rating }: { rating: Promise<number> | number }) {
const value = resolveDeferred(rating);
// Still a promise: show a placeholder (or hand it to DeferredData).
if (value instanceof Promise || value === undefined) return <span>…</span>;
return <span>{value} / 5</span>;
}
Example
import { resolveDeferred } from '@salla.sa/twilight-theme-engine/components/common';
export function Rating({ rating }: { rating: Promise<number> | number }) {
const value = resolveDeferred(rating);
// Still a promise: show a placeholder, or hand it to DeferredData.
if (value instanceof Promise || value === undefined) return <span>…</span>;
return <span>{value} / 5</span>;
}
How it behaves
null,undefinedand anything that is not aPromisecome back unchanged.For a promise it attaches the same tracking
DeferredDatauses, then returns the value when that tracking says resolved, and the promise otherwise (pending or rejected). It never throws.Because the tracking is shared, a promise
DeferredDatahas already rendered resolves synchronously here.
Gotchas
The first call on a promise always returns the promise, even one that resolved long ago: the tracking is filled in by a
.thencallback, which runs only after the current code finishes. Call it again on a later render.A rejected promise also comes back as the promise, so "still a promise" does not mean "still loading". Hand it to
DeferredData, which throws the error to an error boundary.
Related
Source and docs
- Engine source:
packages/theme-engine/src/components/common/DeferredData.tsx