Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Promise.all to key value results

I was wondering if there is an elegant way to achieve the following:

const res = await Promise.all([taskA, taskB])

Where res will become:

{
taskA: <result of taskA>,
taskB: <result of taskB>
}

(The main reason I’m using Promise.all is because I want to run those tasks in parallel, even though they are distinct in nature).

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Totally possible. First, what you need to do is map through all of the tasks you want to do, returning a new array of promises that generate an entry name based on the name of the function and an entry value based on the awaited result:

const taskA = async () => Promise.resolve().then(() => 'foo');
const taskB = async () => Promise.resolve('bar');

(async () => {
    const results = Object.fromEntries(await Promise.all([taskA, taskB].map((func) => (async () => [func.name, await func()])())));

    console.log(results);
})();

Here’s something with a bit more explanation (and easier to read):

const taskA = async () => Promise.resolve().then(() => 'foo');
const taskB = async () => Promise.resolve('bar');

const prettyPromiseAll = async (funcs: Array<(...args: any) => Promise<any>>) => {
    // Since we're generating an array of entries, we can create an object from them
    // once all promises have been awaited.
    return Object.fromEntries(
        // Call Promise.all as normal, making sure to await it.
        await Promise.all(
            // But, for each function...
            funcs.map((func) => {
                // Return an automatically invoked async function (returning a promise)
                // that returns a tuple looking like [nameOfFunction, resultOfPromise]
                return (async () => [func.name, await func()])();
            })
        )
    );
};

(async () => {
    const results = await prettyPromiseAll([taskA, taskB]);

    console.log(results);
})();

Why is this better than the answer below? Because in the answer below, you need to specify the keys for which you’d like the results to have. This method uses the function name.

Note:

This prettyPromiseAll function works differently from regular Promise.all, as it takes an array of functions that return promises, rather than an array of promises.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading