简体   繁体   中英

Waiting for promises inside the object to resolve

I have an object that has promises as its values. The object fields could have different types of values such as functions, promises, strings, numbers, or another object. How do I implement a function which waits for all the promises in the object to resolve?

 const asyncFunction = () => { return Promise.resolve("Resolved!") } const nonAsyncFunction = () => { return "Resolved!" } const awaitObjectWithPromise = (obj) => { // Returns a promise which waits for all // the promises inside "obj" to be resolved. } let obj = { key1: asyncFunction(), key2: nonAsyncFunction(), key3: "Some Value", parent1: { key1: asyncFunction(), key2: nonAsyncFunction(), key3: "Some Value" } } awaitObjectWithPromise(obj).then((obj) => { console.log(obj); // Should output: // { // key1: "Resolved!", // key2: "Resolved!", // key3: "Some Value", // parent1: { // key1: "Resolved!", // key2: "Resolved!", // key3: "Some Value" // } // } })

You can iterate through the keys of the object and solve the promises.

 const asyncFunction = () => { return Promise.resolve("Resolved!") } const nonAsyncFunction = () => { return "Resolved!" } const awaitObjectWithPromise = async(obj) => { for (let prop in obj) { // If the propriety has a 'then' function it's a Promise if (typeof obj[prop].then === 'function') { obj[prop] = await obj[prop]; } if (typeof obj[prop] === 'object') { obj[prop] = await awaitObjectWithPromise(obj[prop]); } } return obj; } let obj = { key1: asyncFunction(), key2: nonAsyncFunction(), key3: "Some Value", parent1: { key1: asyncFunction(), key2: nonAsyncFunction(), key3: "Some Value" } } awaitObjectWithPromise(obj).then((obj) => { console.log(obj); });

In the accepted answer, I was not happy with some things:

  • an error is thrown if one of the fields is null or undefined ;
  • the input value cannot be a Promise;
  • lack of parallelism of waiting for Promises;

To fix these things, I changed the function:

const promiseAll = async (obj) => {
    if (obj && typeof obj.then == 'function') obj = await obj;
    if (!obj || typeof obj != 'object') return obj;
    const forWaiting = [];
    Object.keys(obj).forEach(k => {
        if (obj[k] && typeof obj[k].then == 'function') forWaiting.push(obj[k].then(res => obj[k] = res));
        if (obj[k] && typeof obj[k] == 'object') forWaiting.push(promiseAll(obj[k]))
    });
    await Promise.all(forWaiting);
    return obj;
}

Maybe for someone, it will be useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM