【问题标题】:Waiting till inner promises are done等到内心的承诺完成
【发布时间】:2022-01-12 06:53:46
【问题描述】:

我想等待两个或多个 Promise 被阻止,只要结果对我来说是可用的。

因此我使用Promise.allSettled 方法。如果两个 Promise 是平的,这是可行的。但是,如果其中一个 Promise 包含内部 Promises,那么它将不起作用。

 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 在第二个中没有结果,我怎样才能让它工作。

{状态:“已完成”,值:页面} {状态:“已完成”,值:未定义}

【问题讨论】:

  • 我不遵循您的代码,但是如果您从 return 处理程序中的 return 将它们链接在一起,则内部承诺只能由外部/包含承诺跟踪。而且,您也无法在.forEach() 循环中正确执行此操作,因为从.forEach() 循环中返回任何内容都不会去任何地方。您可能需要改为使用for 循环。而且,如果你需要在一个循环中跟踪所有的 Promise,那么使用 Promise.all()Promise.allSettled() 那里。
  • @jfriend00 你能用伪代码写一个例子吗,我想我不能百分百追随你
  • 我试图重写你的exportVisualData() 函数,但是当你写return visualDescriptor?.exportData(ExportDataType.Summarized); 时我不知道你的意思。你想把它归还给什么?你在一个循环中,所以当你到达那个语句时你是试图退出循环,还是你试图从循环的每次迭代中累积结果?我很困惑这段代码应该做什么。该返回值应该去哪里?其中N个应该去哪里?
  • visualDescriptor?.exportData(ExportDataType.Summarized) 是 Power BI API (playground.powerbi.com/de-de/dev-sandbox) 中的一种方法。我目前的目标是仅导出一个示例视觉对象的数据。最后,我想在一个函数调用中收集来自不同视觉对象的数据,作为数组的一部分。因此,我必须将输入从字符串更改为字符串数组。
  • 好的,所以你想要一个包含多少匹配结果的平面数组?

标签: typescript promise


【解决方案1】:

这是一个重写的exportVisualData() 函数,它将满足您的visualDescriptor.name 测试的任何结果收集到一个数组中,并使该数组成为exportVisualData() 返回的承诺的解析值。

我不知道visualDescriptor?.exportData(ExportDataType.Summarized) 是否返回承诺。如果是这样,我在它前面放了一个await。如果它只是直接返回一个值,你可以删除那个await

另外,我不知道 TypeScript,所以您必须在此代码中添加类型信息:

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;
}

注意,这不会并行运行所有这些异步操作,因此不需要在结果上使用Promise.allSettled()。它只返回一个解析为值数组的 promise。

如果你想在这个函数中捕捉错误并继续处理,你可以在每个循环中尝试/捕捉,在catchcontinue

如果您想并行运行所有内容,则在此处编写代码会更加困难,因为您的 if (visualDescriptor.name === id) 想要跳过某些项目,因此您不知道要等待多少结果,直到您深入了解结果。

【讨论】:

    猜你喜欢
    • 2018-07-21
    • 2020-11-20
    • 2017-06-17
    • 2019-05-31
    • 1970-01-01
    • 2016-10-16
    相关资源
    最近更新 更多