typescript 我如何使用 catchError() 并仍然使用 rxJs 6.0 返回类型化的 Observable?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50245202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:23:56  来源:igfitidea点击:

How do I use catchError() and still return a typed Observable with rxJs 6.0?

angulartypescripttypescript-typingsrxjs6

提问by Rick Strahl

cdSo I'm trying to migrate some of my Angular 5 code to 6, and I understand most of the changes required for rxjs to work using the .pipe() operator. It works as you would expect for 'pipable' operations.

cdSo 我正在尝试将我的一些 Angular 5 代码迁移到 6,并且我了解使用 .pipe() 运算符使 rxjs 工作所需的大部分更改。它的工作原理与您对“可管道”操作的期望相同。

However, the behavior of catchError()is different than the .catch()operator. Prior to rxjs 6 I used the .catch()operator to transform the error input into a a consistent error object that can then be caught in the `.subscribe().

但是,的行为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().parseObservableResponseErroris a function that takes a error object as input and parses the input error into a simpler error object with a normalized object. Catch returns Observable<any>:

new ErrorInfo().parseObservableResponseError是一个函数,它将一个错误对象作为输入,并将输入的错误解析为一个带有规范化对象的更简单的错误对象。捕获返回Observable<any>

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

This worked great for easily handling errors up rxjs5 - errors basically are captured as part of the pipeline and then throw a well known error structure that can be captured .subscribe()error function.

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

Moving that same code to rxjs 6 however and using .pipe()I am trying to do the following:

然而,将相同的代码移动到 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)                        
                );           
}

However this doesn't work because catchError now returns a result of Observable<any>into the pipeline, which is not what I want here. In essence I just want to re-throw any errors as I did before.

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

error TS2322: Type 'Observable<{} | Album[]>' is not assignable to type 'Observable'

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

How do simulate the old operator .catch()behavior?

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

Update:

更新:

After mucking around with this a bit more, the code as shown just started working without giving me a build error. Honestly I have no idea why it failed with the error message before, but is working now. The suggestion by @cartant in the comments is an explicit way to specify the result and that works as well.

在稍微解决这个问题之后,所示的代码开始工作而没有给我一个构建错误。老实说,我不知道为什么它之前因错误消息而失败,但现在正在工作。@cartant 在评论中的建议是指定结果的明确方式,并且也有效。

回答by cartant

You should be able to explicitly specify the type parameters to catchErrorto indicate that it won't return an observable that emits a value - that is, it will return Observable<never>- and will always throw:

您应该能够明确指定类型参数以catchError指示它不会返回发出值的 observable - 也就是说,它将返回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)
        );           
}

Doing so will see the type inferred from the pipecall to be Observable<Album[]>.

这样做将看到从pipe调用推断的类型为Observable<Album[]>.