# Underlying class/utils

[<mark style="background-color:yellow;">ReadablePromise with readAsync demo.</mark>](https://codesandbox.io/s/elated-haibt-c7u1cq)

## ReadablePromise

[Represents an ongoing promise that is readable by React components.](#user-content-fn-1)[^1] It provides a read method for suspending React components until the promise is resolved.

```tsx
const fetchStuff = new ReadablePromise(async () => {
  // fetch stuff
});

function App() {
  const Loading = () => {
    return <p>Loading...</p>;
  };

  const Content = () => {
    const stuff = fetchStuff.read();

    return <p>{stuff.property}</p>;
  };

  return (
      <Suspense fallback={<Loading />}>
        <Content />
      </Suspense>
  );
}
```

`ReadablePromise` implements the implicit contract for integration with concurrent APIs.

### Details

```javascript
class ReadablePromise<T> {
  constructor(executor: () => Promise<T> | T);

  public then = (onFulfilled?: (value?: T) => unknown) => ReadablePromise<T>;

  public read = (): Promise<void> | Error | T;
}
```

#### `constructor(executor: () => Promise | T)`

Creates a new `ReadablePromise` instance.

#### `then(onFulfilled?: (value?: T) => unknown)`

Attaches a callback to the promise, which will be called when the promise is either resolved or rejected. The callback receives the resolved value or the rejection reason as its argument.&#x20;

This method returns the same `ReadablePromise` instance, so it can be chained with other then methods.

#### `read(): Promise | Error | T`

Reads the current state of the promise. If the promise is still pending, this method will throw the pending promise. If the promise has been rejected, this method will throw the rejection reason. Otherwise, this method will return the resolved value of the promise.

## readAsync

`readAsync` is a helper function that helps [create a new instance of the ReadablePromise class and returns its read method in a single step](#user-content-fn-1)[^1].&#x20;

It takes an `executor` function as an argument, which should be a function that returns a value or a promise.&#x20;

```tsx
const fetchStuff = new readAsync(async () => {
  // fetch stuff
});

function App() {
  const Loading = () => {
    return <p>Loading...</p>;
  };

  const Content = () => {
    const stuff = fetchStuff();

    return <p>{stuff.property}</p>;
  };

  return (
      <Suspense fallback={<Loading />}>
        <Content />
      </Suspense>
  );
}
```

[^1]:
