Reputation: 632
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"
// }
// }
})
Upvotes: 3
Views: 2369
Reputation: 1580
In the accepted answer, I was not happy with some things:
null
or undefined
;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.
Upvotes: 5
Reputation: 419
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);
});
Upvotes: 3