如何根据 Angular 中观察者错误回调中的 http 状态代码错误处理订阅

how to handle a subscription based on an http status code error in the observer error callback in Angular

我想知道在以下情况下避免嵌套订阅的最佳方法。 我有一个 API 休息电话,如果用户令牌已过期,它可以 return 一个 401 未授权状态代码。这是在订阅的错误回调中处理的。当调用错误回调时,它会打开一个 angular material 对话框,但只有当收到的错误具有 401 代码时,用户才必须在对话框关闭事件时被重定向到登录页面。为了最后一个目的,我订阅了 dialogRef 实例的 afterClosed() 流:

this.api.fetchData().subscribe({
                         next: (data) => {
                            // do something with data
                        },
                        error: (e: {status_code: number, message: string}) => {
                            const dialogRef = this.dialog.open(DialogErrorComponent, {
                                data: {text: e.message},
                                panelClass: 'my-dialog'
                            });
                            if (e.status_code === 401) {
                                dialogRef.afterClosed().subscribe((res) => {
                                    this.router.navigate(['login']);
                                })
                            }
                        }
                    });

如何重构该代码以避免嵌套订阅,但仅在错误回调中满足条件时保持订阅 afterClosed() 的目的?

以下是(对我来说,最后)最“完全不改变语义的重构”解决方案。

我正在捕获错误并将其转换为从不发出任何内容的流。这并不比您使用的嵌套订阅好多少,但它确实允许在将来使用一些更有趣的方法来管理错误。

如果您决定 re-emit 某些错误,或者在错误发生后 re-try,或者其他什么,现在应该是非常无缝的。例如,这也会让您 return 对话框中可以作为 data/error/etc.

发出的内容
this.api.fetchData().pipe(

  catchError((e: {status_code: number, message: string}) => {

    const dialogRef = this.dialog.open(DialogErrorComponent, {
      data: {text: e.message},
      panelClass: 'my-dialog'
    });

    return e.status_code === 401 ? dialogRef.afterClosed().pipe(
      tap(_ => this.router.navigate(['login'])),
      ignoreElements()
    ) : EMPTY;
  })

).subscribe({
  next: (data) => {/* do something with data */}
});

另一方面,如果您非常确定您永远不会扩展它...我不知道...您的代码看起来很简单 read/reason。