Skip to content

Instantly share code, notes, and snippets.

@pmn4
Created November 3, 2023 14:38
Show Gist options
  • Save pmn4/cd9f75777dcb7fd9ebca34f112888075 to your computer and use it in GitHub Desktop.
Save pmn4/cd9f75777dcb7fd9ebca34f112888075 to your computer and use it in GitHub Desktop.
Predicates for Cleanly Handling Settled Promises
// Filtering
export function isFulfilled<T>(
value: PromiseSettledResult<T>,
_index?: number,
_array?: PromiseSettledResult<T>[],
): value is PromiseFulfilledResult<T> {
return value.status === 'fulfilled';
}
export function isRejected<T>(
value: PromiseSettledResult<T>,
_index?: number,
_array?: PromiseSettledResult<T>[],
): value is PromiseRejectedResult {
return value.status === 'rejected';
}
// Mapping
export function promisedValue<T>(
promise: PromiseFulfilledResult<T>,
_index?: number,
_array?: PromiseFulfilledResult<T>[],
): T {
return promise.value;
}
export function rejectedReason(
promise: PromiseRejectedResult,
_index?: number,
_array?: PromiseRejectedResult[],
): PromiseRejectedResult['reason'] {
return promise.reason;
}
@pmn4
Copy link
Author

pmn4 commented Nov 3, 2023

Use these filter and map functions to clean up your Promise handling, without having to import a bunch of types.

Go from:

  settledPromises
    .filter((s): s is PromiseFulfilledResult<Datum> => s.status === 'fulfilled')
    //      ^^^ routine code where you must know the type... lame!
    .map((s) => s.value)
    //   ^^^ more routine code
    .sort(({ priority: a }, { priority: b }) => a - b)

To:

  settledPromises
    .filter(isFulfilled)
    .map(promisedValue)
    .sort(({ priority: a }, { priority: b }) => a - b);
    // see my other gists for even more readability: https://gist.github.com/pmn4
    // .sort(byNumericFieldValue('priority'))

full example:

type Datum = { name: string, priority: number };

(async () => {
  const post1: Datum = { name: 'First', priority: 1 };
  const post3: Datum = { name: 'Third', priority: 10 };

  const settled = await Promise.allSettled([
    Promise.resolve({ name: 'First', priority: 1 }),
    Promise.reject('error'),
    Promise.resolve({ name: 'Third', priority: 10 }),
  ]);

  const sortedData = settled
    .filter(isFulfilled)
    .map(promisedValue)
    .sort(({ priority: a }, { priority: b }) => a - b);

  const errors = settled.filter(isRejected).map(rejectedReason);

  console.log({ sortedData, errors });

})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment