簡體   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