首页 > 解决方案 > 如何在 Angular 6(使用 rxjs 6)中订阅多个 HTTP 请求并确保发出所有请求,即使其中一个会引发错误

问题描述

我有三个 observables,由 HttpClient 的 get() 方法返回。我使用 forkJoin 运算符是为了在所有请愿结束时获得信号。

const responses = [
  this.http.get('http://localhost:3000/articles').pipe(
    map( data => this.articles = data ),
    catchError( err => throwError("Can't get the articles list") )
  ),
  this.http.get('http://localhost:3000/notas').pipe(
    map( data => this.news = data ),
    catchError( err => throwError("Can't get the news list") )
  ),
  this.http.get('http://localhost:3000/users').pipe(
    map( data => this.users = data ),
    catchError( err => throwError("Can't get the users list") )
  )
];

forkJoin(responses).pipe(
  catchError( err => throwError(err) )
).subscribe(
  response => console.log('All data loaded')
);

如果第一个 HTTP 请求抛出错误,则发出其他 HTTP 请求,但不执行相应的回调。我在rxjs 文档上读到“如果在某些时候有任何输入 Observable 错误,forkJoin 也会出错,并且所有其他 Observable 将立即取消订阅。”。所以我猜我的 forkJoin 正在按预期工作,但是我没有得到我需要的功能。

那么:我如何使用 forkJoin 或任何等效方法确保发出所有请求并执行所有回调,即使其中一个抛出错误?

标签: angularobservablerxjs6

解决方案


我终于管理它创建了一个自定义的可观察对象,当所有内部可观察对象都发出或抛出错误时发出:

  public allRequests(requests: Observable<any>[]): Observable<any> {
    return new Observable(
      observer => {
        requests.forEach((request, i) => {
          request.subscribe(
            resp => {
              emitOnLast(i);
            },
            err => {
              emitOnLast(i);
              console.error(err);
            }
          );
          const emitOnLast = (n: number) => {
            if (n === requests.length - 1) {
              observer.next(this.msg);
            }
          };
        });
      }
    );
  }

推荐阅读