将函数传递给 catchError

Passing a function to catchError

我定义了一个简单的函数,它将打开一个 MatSnackBar 并在 get 请求 returns 任何错误时显示错误消息

handleError(err: HttpErrorResponse) {
    this.snackBar.open(err.message)
    return throwError(err)
}

所以当我在构造函数中订阅一个可观察对象时,我将上述函数传递给 catchError

constructor(private snackBack: MatSnackBar) {
...
this._obv$ = this.myService.getTypes().pipe(
  catchError(this.handleError)
)
...

触发错误时,传递给 handleErrorerr 是正确的,但 this.snackBarundefined

当我像这样使用 handleError 函数时问题消失了

this._obv$ = this.myService.getTypes().pipe(
  catchError(err => this.handleError(err)
)

有什么区别,为什么 snackBar 实例 undefined

问题

问题是当在对象上调用函数时,该对象作为函数上下文(它的 this)被隐式传递。有时您会看到这种调用样式称为 method 而不是 function.

方法被隐式地赋予允许它们操作其属性的对象。但是,您可以明确表示这种关系。

this.handleError,不调用该函数,它只是传递对它的引用。现在 catchError 不知道它需要调用 this.handleError(err) 而不是 handleError(err).

通常,如果函数使用 this 关键字,则调用者负责提供 this 上下文。使用点符号使这非常直观,但在极端情况下会导致奇怪的行为。


解决方案:

一个解决方法是使用 lambda 函数为您执行该步骤。 Lamda 函数(使用箭头 => 语法)始终保留相对于它们定义位置的上下文。所以在这种情况下,this 指的是你所期望的。

另一种解决方案是将正确的对象绑定到函数调用(这使您可以将函数作为绑定对象的方法来调用)。在某些情况下,此变通方法更可靠,因为它允许您将 any 上下文绑定到函数。但是,在这种情况下,您只是绑定当前上下文。

像这样:

constructor(private snackBack: MatSnackBar) {
...
this._obv$ = this.myService.getTypes().pipe(
  catchError(this.handleError.bind(this))
)
...