我要实现的目标与此处描述的目标非常相似: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
,也会发生相同的行为。这些都可以满足我的要求。
建议?
答案 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])
);