等到内心的承诺完成

Posted

技术标签:

【中文标题】等到内心的承诺完成【英文标题】: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) 中的一种方法。我目前的目标是仅导出一个示例视觉对象的数据。最后,我想在一个函数调用中收集来自不同视觉对象的数据,作为数组的一部分。因此,我必须将输入从字符串更改为字符串数组。 好的,所以你想要一个包含多少匹配结果的平面数组? 【参考方案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) 想要跳过某些项目,因此您不知道要等待多少结果,直到您深入了解结果。

【讨论】:

以上是关于等到内心的承诺完成的主要内容,如果未能解决你的问题,请参考以下文章

Angular forEach 等到所有承诺都完成?

限制并发并等到所有承诺完成,即使有些拒绝

如何重建自己的内心世界和外部世界?何谓构建外部世界?

我喜欢你时的内心活动

我喜欢你时的内心活动

解放你内心的自然领袖,从你的内心而非你的自我来领导你自己