18

cd所以我正在尝试将我的一些 Angular 5 代码迁移到 6,并且我了解 rxjs 使用 .pipe() 运算符工作所需的大部分更改。它可以像您期望的“pipable”操作一样工作。

但是, 的行为与操作员catchError()不同.catch()。在 rxjs 6 之前,我使用.catch()运算符将​​错误输入转换为一致的错误对象,然后可以在 `.subscribe() 中捕获该对象。

getAlbums(): Observable<Album[]> {
     return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
           .map(albumList => this.albumList = albumList)
           .catch(new ErrorInfo().parseObservableResponseError);            
    }

new ErrorInfo().parseObservableResponseError是将错误对象作为输入并将输入错误解析为具有规范化对象的更简单错误对象的函数。抓住回报Observable<any>

parseObservableResponseError(response): Observable<any> {
    let err = new ErrorInfo();
    ...
    return Observable.throw(err);        
}

这对于轻松处理 rxjs5 上的错误非常有用 - 错误基本上被捕获为管道的一部分,然后抛出一个众所周知的错误结构,可以捕获.subscribe()错误函数。

然而,将相同的代码移动到 rxjs 6 并使用.pipe()我正在尝试执行以下操作:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
                .pipe(
                    map(albumList => this.albumList = albumList),
                    catchError(new ErrorInfo().parseObservableResponseError)                        
                );           
}

但是这不起作用,因为 catchError 现在将结果返回Observable<any>到管道中,这不是我想要的。本质上,我只想像以前一样重新抛出任何错误。

错误 TS2322:类型 'Observable<{} | 专辑 []>' 不可分配给类型 'Observable'

如何模拟旧的操作员.catch()行为?

更新:

在对此进行了更多处理之后,显示的代码刚刚开始工作,而没有给我一个构建错误。老实说,我不知道为什么它之前失败并显示错误消息,但现在正在工作。@cartant 在评论中的建议是一种明确的方式来指定结果,并且效果也很好。

4

1 回答 1

24

您应该能够显式指定类型参数以catchError指示它不会返回发出值的可观察对象 - 也就是说,它将返回Observable<never>- 并且总是会抛出:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
        .pipe(
            map(albumList => this.albumList = albumList),
            catchError<Album[], never>(new ErrorInfo().parseObservableResponseError)
        );           
}

这样做会看到从pipe调用中推断出的类型是Observable<Album[]>

于 2018-05-09T06:28:25.760 回答