subscribe中的onError和catch操作符有什么区别?

3

我遇到了 RxJS 中的两种错误处理方式:

  • 使用 subscribe 的第二个参数 (onError)
  • 使用 catch 操作符。

它们之间有何区别?有哪些使用它们的经典例子或规则?


this.stream$.subscribe(callback, err => console.error(err))

// vs

this.stream$.catch(err => console.error(err)).subscribe(callback)

根据 https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93,关于错误传播的部分。 - user3743222
2
传递给 catch 操作符的选择器函数返回一个可观察对象,用于继续链式操作。但是对于传递给 subscribe 的错误处理程序没有类似的行为。 - cartant
2个回答

2
在你的例子中,无论使用哪种方式都会得到相同的输出。以下是一些经验法则:
  • 如果你想要在出现错误时处理该错误(例如记录日志),并且不想创建订阅,那么请使用do。例如,如果你正在将某个库(例如Angular的Http库)包装在通用包装器中,并添加了日志记录功能(例如当出现错误时弹出屏幕底部的消息提示),那么可以使用do
  • 如果你想要在出现错误时处理该错误(例如记录日志),并且想要创建订阅,那么请使用subscribe。继续以Http为例,如果你想要发起一个请求,并在同一位置显示任何出现的错误和响应,则可以使用subscribe
  • 如果你想要处理错误并进行恢复,那么请使用catch。例如,也许你想要捕获401错误、刷新登录凭据,然后重试请求。
在你的例子中,由于你只是记录错误,因此使用catch是不合适的。

1

subscribe 方法的回调函数是整个链条的末端,你只需监听结果。

catch 是一个操作符,当抛出错误或仅替换错误为其他值时,它允许您更改可观察对象的行为。 catch 期望你做一些事情,返回一个新的可观察对象而不仅仅是监听它。

此外,你可以在链中使用 do 来像在 subscribe 中一样监听可观察对象。

* 对于 RxJs 6 *

使用 tap 替代 do。 使用 catchError 替代 catch。 使用 finalize 替代 finally

对于上述所有参数,都需要使用管道:

this.service.getItem()
    .pipe(
        map((data) => this.onSuccess(data)),
        catchError(error => of(this.handleError(error))),
        finalize(() => this.stopLoading())
    )
    .subscribe();

此外,导入方式已经改变。现在你应该这样导入:
Import { tap, catchError } from 'rxjs/operators';

此句话的英译中文为:

此外,您无需导入管道。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接