如何在 Observable.forkJoin(...) 中捕获错误?

Posted

技术标签:

【中文标题】如何在 Observable.forkJoin(...) 中捕获错误?【英文标题】:How to catch error in Observable.forkJoin(...)? 【发布时间】:2018-12-08 18:29:43 【问题描述】:

我使用Observable.forkJoin() 处理两个 HTTP 调用完成后的响应,但如果其中任何一个返回错误,我该如何捕捉该错误?

Observable.forkJoin(
  this.http.post<any[]>(URL, jsonBody1, postJson) .map((res) => res),
  this.http.post<any[]>(URL, jsonBody2, postJson) .map((res) => res)
)
.subscribe(res => this.handleResponse(res))

【问题讨论】:

这取决于您想要实现的目标。如果其中一个调用失败,那么整个 observable 都会失败,您可以在订阅者中处理它。 【参考方案1】:

这对我有用:

forkJoin(
 this.http.post<any[]>(URL, jsonBody1, postJson).pipe(catchError(error => of(error))),
 this.http.post<any[]>(URL, jsonBody2, postJson)
)
.subscribe(res => this.handleResponse(res))

即使第一次调用出错,第二次HTTP调用也会正常调用

【讨论】:

【参考方案2】:

你有没有在这几行之间尝试过一些东西?

const todo1$ = this.myService.getTodo(1);
const error$ = this.myService.getTodo(201);
const todo2$ = this.myService.getTodo(2);
forkJoin([todo1$, error$, todo2$])
  .subscribe(
    next => console.log(next),
    error => console.log(error)
  );

请记住,如果在某些时候任何输入 observable 错误,forkJoin 也会出错,并且所有其他 observable 将立即取消订阅。

【讨论】:

应该提到catchError以避免发生任何错误时丢失所有链。 我的情况是,我想打破链条,因此这对我有用。【参考方案3】:

您可以catch 传递给forkJoin 的每个可观察对象中的错误:

// Imports that support chaining of operators in older versions of RxJS
import Observable from 'rxjs/Observable';
import forkJoin from 'rxjs/add/observable/forkJoin';
import of from 'rxjs/add/observable/of';
import map from 'rxjs/add/operator/map';
import catch from 'rxjs/add/operator/catch';

// Code with chaining operators in older versions of RxJS
Observable.forkJoin(
  this.http.post<any[]>(URL, jsonBody1, postJson) .map((res) => res)).catch(e => Observable.of('Oops!')),
  this.http.post<any[]>(URL, jsonBody2, postJson) .map((res) => res)).catch(e => Observable.of('Oops!'))
)
.subscribe(res => this.handleResponse(res))

另外请注意,如果你使用 RxJS6,你需要使用catchError 而不是catch,以及pipe 运算符而不是链接。

// Imports in RxJS6
import forkJoin, of from 'rxjs';
import map, catchError from 'rxjs/operators';

// Code with pipeable operators in RxJS6
forkJoin(
  this.http.post<any[]>(URL, jsonBody1, postJson) .pipe(map((res) => res), catchError(e => of('Oops!'))),
  this.http.post<any[]>(URL, jsonBody2, postJson) .pipe(map((res) => res), catchError(e => of('Oops!')))
)
  .subscribe(res => this.handleResponse(res))

【讨论】:

我收到一条错误消息,指出http.post().map().catch() 不是函数 你导入了 catch 吗? @matchifang 我可以使用管道方式解决这个问题http.post().pipe(map().catch()) 我们真的需要map吗?我的意思是catchError 是强制性的还是pipe 的一个例子? 您不需要map,只需catchError

以上是关于如何在 Observable.forkJoin(...) 中捕获错误?的主要内容,如果未能解决你的问题,请参考以下文章

Rxjs:Observable.combineLatest vs Observable.forkJoin

Observable.forkJoin() 不执行

函数返回后 Observable.forkJoin 调用延迟

Observable forkJoin 从不执行管道

ForkJoin 2 BehaviorSubjects

显示错误并恢复流