即使一个失败并且已经有一个catchError管道,CombineLatest也会继续

时间:2020-04-07 17:06:25

标签: angular rxjs

我要实现的目标与此处描述的目标非常相似:Observable.combineLatest continue even if one fails

主要区别在于,我的服务已经具有处理错误请求并返回throwError的组件。

服务:

get(): Observable<Array<MyObject>> {
    return this.client.get<Array<MyObject>>('/api').pipe(
      map(response => this.flattenMyObject(response)),
      catchError(ServiceHandler.error)
    );
  }

两个呼叫都和上面一样,只是端点不同

ServiceHandler:

export namespace ServiceHandler {
  export function error(err: HttpErrorResponse) {
    if (err.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', err.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${err.status}, ` + `body was: ${err.error}`
      );
    }
    // return an observable with a user-facing error message
    return throwError('Something bad happened; please try again later.');
  }
}

组件:

    const observable1$ = this.myService.get()
      .pipe(take(1));
    const observable2$ = this.myService.getOther().pipe(take(1));

    const result$ = zip(observable1$, observable2$).pipe(
      map(([list1, list2]) => {
        let concatenedList = [];

        const hasList1 = !!list1 && list1.length > 0;
        const hasList2 = !!list2 && list2.length > 0;

        if (hasList1) {
          concatenedList = concatenedList.concat(list1);
        }

        if (hasList2) {
          concatenedList = concatenedRulesList.concat(list2);
        }

        return concatenedList;
      })
    );
    this.gridData$ = result$;
  }

问题在于,当其中一个调用失败时,第一个调用将被取消并且什么也不会返回。如果在我的服务中将catchError更改为:catchError(() => of(null)),则当一次调用失败时,输出不会受到影响,并且成功调用的结果将加载到我的类变量gridData$上。

如果我使用.zip.forkjoin.combineLatest,也会发生相同的行为。这些都可以满足我的要求。

建议?

1 个答案:

答案 0 :(得分:0)

我了解的是,您希望代码在记录错误之后像没有错误一样继续执行吗? 您的服务已经在处理错误,然后转发错误,那么您的组件可以捕获转发的错误,将其忽略,然后发出并清空列表,一切都应按预期工作,因为您忽略了抛出的错误,我也会在这种情况下,请使用CombineLatest,除非您严格要求维护发射值序列

   const observable1$ = this.myService.get()
                  .pipe(
                        take(1),
                        catchError(_ => of([]))
                   );

    const observable2$ = this.myService.getOther()
                  .pipe(
                        take(1),
                        catchError(_ => of([]))
                  );



 this.gridData$ = combineLatest(observable1$, observable2$)
                  .pipe(
                        map(([list1, list2]) => [...list1,...list2])
                   );