简体   繁体   English

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

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

I need wait for two requests (observables) and do some things.我需要等待两个请求(可观察对象)并做一些事情。 What i need:我需要的:

  1. Wait for requests (observables) end等待请求(可观察对象)结束
  2. If one of them failed - display one error如果其中之一失败 - 显示一个错误
  3. If both of them failed - display second error如果它们都失败了 - 显示第二个错误
  4. If first success - do some things如果第一次成功 - 做一些事情
  5. If second success - do some things如果第二次成功 - 做一些事情

i can combine 4 and 5 if that matter for errors handling.如果这对错误处理很重要,我可以将 4 和 5 结合起来。

I tried to use forkJoin but it fails at all if one of requests failed.我尝试使用forkJoin但如果其中一个请求失败,它就会失败。
I tried to use concat but it works the same as forkJoin我尝试使用concat但它的工作原理与forkJoin相同
I tried to use combineLatestWith but it doesn't display errors at all as combineLatest我尝试使用combineLatestWith但它根本不显示错误为combineLatest
Finally i tried to use next:最后我尝试使用下一个:

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

and now i got only both success results and didn't get any error What im missing?现在我只得到了两个成功结果并且没有得到任何错误我错过了什么?

catch your errors at the request level and transform them into something usable:在请求级别捕获您的错误并将它们转换为可用的内容:

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. You need to use forkJoin for this use case, See ForkJoin docs .对于此用例,您需要使用forkJoin ,请参阅ForkJoin 文档

  2. Add catchError operator to the first stream to handle the first requestcatchError运算符添加到第一个流以处理第一个请求

  3. Add another catchError operator to the second stream to handle it将另一个catchError运算符添加到第二个流以处理它

  4. Add tap operator to the first stream 1tap运算符添加到第一个流 1

  5. Add another tap operator to the first stream 2将另一个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
  }
});

I had a case where one request normally takes much longer than the other, so in the success case I don't want to have to wait for both requests to finish before continuing.我遇到过一个请求通常比另一个请求花费更长的时间的情况,因此在成功的情况下,我不想在继续之前等待两个请求都完成。 As soon as one request finishes, I want to show the received data to the user.一旦一个请求完成,我想向用户显示接收到的数据。 But the error handling needed to be different if both requests failed, than if just one failed or when both succeeded.但是如果两个请求都失败,错误处理需要不同,而不是只有一个失败或两个都成功。

So I did this:所以我这样做了:

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

The Errors are only processed after both requests finished, but the individaul data can get processed right away.错误仅在两个请求完成后处理,但可以立即处理单个数据。

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

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