I have an array of accounts and there are two request one is to get domain and from that get data of account. if i have to get all accounts data how can i do it?
accountsData = acounts.map(account => {
getDomain(account).then(domain => getData(domain))
})
Promises.all(accountsData).then(e => console.log(e))
Since the few request all failing so this is not working.
I have tried the above aproch and it not works when few request fails.
CodePudding user response:
Promise.allSettled
Use Promise.allSettled to check if the promise is fulfilled or rejected.
You can push the promises into an array and use Promise.allSettled on the promise array.
Solution
for (const account of accounts) {
getDomainPromises.push(getDomain(account));
}
await Promise.allSettled(getDomainPromises).then((getDominResults) =>
getDominResults.forEach((getDomainResult) => {
if (getDomainResult.status === 'fulfilled'){
console.log("GD - " getDomainResult.status, getDomainResult.value);
getDataPromises.push(getData(getDomainResult.value))
} else { // status = 'rejected'
console.log("GD - " getDomainResult.status);
}
})
);
await Promise.allSettled(getDataPromises).then((getDataResults) =>
getDataResults.forEach((getDataResult) => {
if (getDataResult.status === 'fulfilled'){
console.log("getData - ", getDataResult.value)
} else { // status = 'rejected'
console.log("getData - REJECTED");
}
})
);
Working Demo:
// Mocking getDomain Promise
function getDomain(a) {
return new Promise((resolve, reject) => {
if (a % 2 === 0) {
setTimeout(resolve, 100, 'RESOLVE - getDomain - ' a);
} else {
setTimeout(reject, 100, 'REJECTED - getDomain - ' a);
}
})
}
// Mocking getData Promise
function getData(a) {
return new Promise((resolve, reject) => {
if (Math.round(Math.random()*100) % 2 === 0) {
setTimeout(resolve, 100, 'RESOLVE - getData - ' a);
} else {
setTimeout(reject, 100, 'REJECTED - getData - ' a);
}
})
}
// SOLUTION::
const accounts = [1, 2, 3, 4];
const getDomainPromises = [];
const getDataPromises = [];
for (const account of accounts) {
getDomainPromises.push(getDomain(account));
}
async function run() {
await Promise.allSettled(getDomainPromises).then((getDominResults) =>
getDominResults.forEach((getDomainResult) => {
if (getDomainResult.status === 'fulfilled'){
console.log("GD - " getDomainResult.status, getDomainResult.value);
getDataPromises.push(getData(getDomainResult.value))
} else { // status = 'rejected'
console.log("GD - " getDomainResult.status);
}
})
);
await Promise.allSettled(getDataPromises).then((getDataResults) =>
getDataResults.forEach((getDataResult) => {
if (getDataResult.status === 'fulfilled'){
console.log("getData - ", getDataResult.value)
} else { // status = 'rejected'
console.log("getData - REJECTED");
}
})
);
}
run();
CodePudding user response:
You need to return a Promise
on each iteration of the map
accountsData = acounts.map(account => {
return new Promise((resolve, reject) => {
getDomain(account)
.then(domain => getData(domain)
.then(data => resolve(data)))
});
})
// e would be of the format [data1, data2, .....]
Promises.all(accountsData).then(e => console.log(e))