typescript 在执行函数以生成Excel之前,Angular 等待订阅

lf5gs5x2  于 2023-03-09  发布在  TypeScript
关注(0)|答案(1)|浏览(104)

我有一个函数,我从一个API请求生成一个excel。在网页上,我有一个下载按钮,执行函数downloadCSV()。它目前的工作预期,除非我点击链接太快时导航到页面。
在这个函数中,我订阅了数据,并用它填充一个数组,然后用这个数组生成一个excel,无论数组是否填充,excel都会立即下载。
我希望要么重试功能,如果Excel是空的。

等待订阅完成后执行。

downloadCSV (): void {
//list headers
const csvHeaders = [
 'bunch of headers'
];

//initate array
const data: any[] = [];
//get name for each customer
this.nameService.getNames().subscribe({
  next: ({ names }) => {
    //for each customer list details 
    names.forEach(name => {
      //get details
      this.nameService.getPersonalData(name.firstName).pipe(
        tap((data: Idata) => {
          data.push({
            'bunch of data points'
          });
        })
      ).subscribe(
        { error: (err) =>
        { console.error(err); } });
    });
  }
});
const filename = 'dataReport';
    this.generateCSV(data, filename, reportHeaders);

}

generateCSV (data, filename, reportHeader): void {
    new ngxCsv(data, filename, { headers: reportHeader, showTitle: true, title: this.customerDetails });
  }

所以对于getNames函数,我需要使用firstname来获取我想要的实际数据,然后订阅并生成一个excel。
目前,excel可以立即下载,而无需先等待数据填充。

tvokkenx

tvokkenx1#

最好的方法是等待所有订阅结束。
如果你的excel是空的,那可能是因为完全不同的原因。你可能想要具体地处理它们。如果你的请求很大,谁知道你要重试多少次呢?在大多数情况下,随机重试不是好方法。
因此,对于您的情况,我认为rxjs中的forkJoin操作符可以完成这项工作。
简单地说,它会把所有的观察对象合并成一个,所以最后你只有一个订阅(一个订阅对应于所有的getPersonalData请求),只有当所有的观察对象都发出一次,forkJoin才会发出一个值,这也是你想要的。
所以你的代码看起来像这样

this.nameService.getNames().subscribe({
      next: ({ names }) => {
        //for each customer list details
        forkJoin(
          names.map((name) => {
            //get details
            return this.nameService.getPersonalData(name.firstName)
              .pipe(
                 catchError((err) => {
                    console.error(err);
                 }));
          }),
        ).subscribe((datas: Idata[]) => {
          // Do whatever you want with datas before using it
          this.generateCSV(datas, filename, reportHeaders);
        });
      },
    });

等待所有请求发出,然后调用方法。
PS:我没有运行代码,所以它们可能是一些语法错误
PS2:别忘了退订你所有的可观!

相关问题