Skip to content
Twilight React Playground
ثيم رائدaren

resolveDeferred

functionAdvancedserverbrowserlive demo

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

resolveDeferred hands back the value of a promise it already knows has resolved, and the promise itself otherwise.Try this: create a promise, wait past the delay, then call resolveDeferred twice: the first call only starts tracking it, the second returns the value.
Storefront canvas · ar · RTL
Runs in the browser…
Controls
What a theme writes
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

app/components/product/Rating.tsx
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, undefined and anything that is not a Promise come back unchanged.

  • For a promise it attaches the same tracking DeferredData uses, 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 DeferredData has 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 .then callback, 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