繁体   English   中英

RxJS/Angular 11 等待 2 个 observables 完成和错误处理

[英]RxJS/Angular 11 wait for 2 observables complete and errors handling

我需要等待两个请求(可观察对象)并做一些事情。 我需要的:

  1. 等待请求(可观察对象)结束
  2. 如果其中之一失败 - 显示一个错误
  3. 如果它们都失败了 - 显示第二个错误
  4. 如果第一次成功 - 做一些事情
  5. 如果第二次成功 - 做一些事情

如果这对错误处理很重要,我可以将 4 和 5 结合起来。

我尝试使用forkJoin但如果其中一个请求失败,它就会失败。
我尝试使用concat但它的工作原理与forkJoin相同
我尝试使用combineLatestWith但它根本不显示错误为combineLatest
最后我尝试使用下一个:

const firstRequest$ = this.doFirstRequest(searchRequest);
const secondRequest$ = this.doSecondRequest(searchRequest);
combineLatest([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
  console.log(res1, res2);
}, err => {
  console.log(err);
});

现在我只得到了两个成功结果并且没有得到任何错误我错过了什么?

在请求级别捕获您的错误并将它们转换为可用的内容:

const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
  catchError(error => of({error})) 
);
const secondRequest$ = this.doSecondRequest(searchRequest).pipe(
  catchError(error => of({error}))
);
forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
  if (res1.error && res2.error) {
    // both failed
  } else if (res1.error || res2.error) {
    // one failed
  }
  if (!res1.error) {
    // req 1 success 
  }
  if (!res2.error) {
    // req 2 success
  }
  // whatever you need to do now that they're both done
}, err => {
  // can't get here now
});
  1. 对于此用例,您需要使用forkJoin ,请参阅ForkJoin 文档

  2. catchError运算符添加到第一个流以处理第一个请求

  3. 将另一个catchError运算符添加到第二个流以处理它

  4. tap运算符添加到第一个流 1

  5. 将另一个tap运算符添加到第一个流 2

const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
  tap(() => {
    // DO SOMETHING STREAM 1 REGARDLESS OF STREAM 2
  }),
  catchError((e => {
    console.error('Error from stream 1', e);
    return EMPTY;
  });
);

const secondRequest$ = this.doFirstRequest(searchRequest).pipe(
  tap(() => {
    // DO SOMETHING STREAM 2 REGARDLESS OF STREAM 1
  }),
  catchError((e => {
    console.error('Error from stream 2', e);
    return EMPTY;
  });
);

forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
  console.log('All done');

  if (res1) {
    // DO SOMETHING STREAM 1 AFTER ALL STREAMS ARE DONE
  }

  if (res21) {
    // DO SOMETHING STREAM 2 AFTER ALL STREAMS ARE DONE
  }
});

我遇到过一个请求通常比另一个请求花费更长的时间的情况,因此在成功的情况下,我不想在继续之前等待两个请求都完成。 一旦一个请求完成,我想向用户显示接收到的数据。 但是如果两个请求都失败,错误处理需要不同,而不是只有一个失败或两个都成功。

所以我这样做了:

getRequestASucceeded$ = new ReplaySubject<boolean>(1);

this.getRequestA()
    .subscribe( dataA => {
       this.getRequestASucceeded$.next(true);
       // continue with dataA
     },
     (err: HttpErrorResponse) => {
        this.getRequestASucceeded$.next(false);
      }
   );

this.getRequestB()
    .subscribe( dataB => {
       
       // continue with dataB

       this.getRequestASucceeded$.subscribe( hasSucceeded => {
          if (hasSucceeded) {
            // Both Request succeeded
          else {
            // RequestA failed, RequestB succeeded
          }
     },
     (err: HttpErrorResponse) => {
        
        this.getRequestASucceeded$.subscribe( hasSucceeded => {
          if (hasSucceeded) {
            // RequestA succeeded, RequestB failed
          else {
            // Both Request failed
          }
      }
   );

错误仅在两个请求完成后处理,但可以立即处理单个数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM