I want to wait that two or more Promises will be blocked, as long there results will be for me avaible.
Therefore I am using the Promise.allSettled
method. This is working if the two Promises are flat. But if one of that Promises consists of inner Promises then it won't work.
Promise.allSettled([
report?.getActivePage(), //return a Promise object
exportVisualData("9df20366a984c945beb5")
])
.then((results) => {
results.forEach((result, index) => {
if (result.status === "rejected") {
const rejectedResult: PromiseRejectedResult =
result as PromiseRejectedResult;
console.log(rejectedResult);
} else if (result.status === "fulfilled") {
if (index === 0) {
const fulfilledResult: PromiseFulfilledResult<Page | undefined> =
result as PromiseFulfilledResult<Page | undefined>;
console.log(fulfilledResult);
fulfilledResult.value?.setActive();
} else {
const fulfilledResult: PromiseFulfilledResult<void | IExportDataResult> =
result as PromiseFulfilledResult<void | IExportDataResult>;
console.log(fulfilledResult);
}
}
});
function exportVisualData(id: string): Promise<void | IExportDataResult> {
return report!.getPages().then((pages) => {
pages.forEach((page) => {
page.getVisuals().then((visualDescriptors) =>
visualDescriptors.forEach((visualDescriptor) => {
if (visualDescriptor.name === id) {
if (!page.isActive) {
page.setActive().then((__) => {
return visualDescriptor?.exportData(
ExportDataType.Summarized
);
});
} else {
return visualDescriptor?.exportData(ExportDataType.Summarized);
}
}
})
);
});
});
Promise.allSettled hasn't have a result in the second due to the inner promises, how could I can get this to work.
{status: 'fulfilled', value: Page} {status: 'fulfilled', value: undefined}
CodePudding user response:
Here's a rewritten exportVisualData()
function that collects whatever results meet your visualDescriptor.name
test into an array and makes that array the resolved value of the promise that exportVisualData()
returns.
I didn't know if visualDescriptor?.exportData(ExportDataType.Summarized)
returns a promise or not. In case it does, I put an await
in front of it. If it just returns a value directly, you can remove that await
.
Also, I don't know TypeScript so you will have to add type info to this code:
async function exportVisualData(id: string): Promise < void | IExportDataResult > {
const results = [];
const pages = await report!.getPages();
for (let page of pages) {
let visualDescriptors = await page.getVisuals();
for (let visualDescriptor of visualDescriptors) {
if (visualDescriptor.name === id) {
if (!page.isActive) {
await page.setActive();
}
results.push(await visualDescriptor?.exportData(ExportDataType.Summarized));
}
}
}
return results;
}
Note, this does not run all these asynchronous operations in parallel, so there is no need to use Promise.allSettled()
on the result. It just returns a single promise that resolves to an array of values.
If you want to catch errors and keep processing in this function, you can try/catch in each loop and continue
in the catch
.
If you wanted to run everything in parallel, that is more difficult to code here because of your if (visualDescriptor.name === id)
that wants to skip some items so you don't know how many results you are waiting for until you're far into the results.