Promise.all for objects in Javascript

Viewed 3714

Promise.all can turn [Promise a, Promise b] into Promise [a, b], which is super useful, but is there also a way to turn {a: Promise a, b: Promise b} into Promise {a, b}.

The use case is:

I have a function that loads some files from a website and gives back error messages in the case that it failed. This means, that its signature is information -> {values: values, messages: messages}.

But the whole check is async, so it turns out to be information -> {values: Promise values, messages: promise messages}

4 Answers

I would dare to suggest another option (with some further hints):

export async function promiseAllOfObject(obj) {
  const values = await Promise.all(Object.values(obj));
  return Object.keys(obj).reduce(
    (res, key, index) => (res[key] = values[index], res),
    {}
  );
}

Respectively replacing Promise.all to Promise.allSettled will give you promiseAllOfObjectSettled() function.

And, as a small bonus, here is typescript version (replacing to Promise.allSettled works the same as above):

export async function promiseAllOfObject<
  T extends Record<string, unknown> = Record<string, unknown>,
>(obj: {
  [P in keyof T]: Promise<T[P]>;
}): Promise<T> {
  const values = await Promise.all(Object.values(obj));
  return Object.keys(obj).reduce((res, key, index) => {
    res[key] = values[index];
    return res;
  }, {} as Record<string, unknown>) as T;
}
Related