【问题标题】:Angular observable subscribe call same method on next() and error()Angular observable subscribe 在 next() 和 error() 上调用相同的方法
【发布时间】:2020-07-18 20:01:52
【问题描述】:

我有一个返回 observable 的函数,无论这个 observable 返回数据还是错误,我都需要重定向到主页。类似的东西:

  private initializeCurrentUser() {
    this.userService
      .initializeCurrentUser()
      .subscribe(
        () => this.router.navigate(['']), //next
        () => this.router.navigate([''])  //error
      );
  }

有什么方法可以概括 next() 和 error() 调用以防止代码重复?

【问题讨论】:

    标签: angular observable


    【解决方案1】:

    您可以使用catchError 运算符。操作符以 observable 序列处理错误并返回 observable,因此在 subscribe 中您只能获得下一个值。

    RxJS - catchError

    例如:

    private initializeCurrentUser() {
     this.userService
      .initializeCurrentUser()
      .pipe(catchError(() => of()))
      .subscribe(() => this.router.navigate(['']));
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用finalize 运算符:

      private initializeCurrentUser() {
       this.userService
        .initializeCurrentUser()
        .pipe(finalize(() => this.router.navigate([''])))
        .subscribe(() => {});
      }
      

      【讨论】:

        【解决方案3】:

        我相信答案是否定的,你不能一概而论nexterror 因为subscribe 期待每个回调。有几个选项,但我认为它们的代码更多,不太清楚。让我们看一个,看看为什么。

        Observable.subscribe 有两种不同的调用方式。一种是像上面那样传递nexterrorcomplete 的回调。另一种方法是传递一个Observer 对象。这个Observer 对象可以让你做你所要求的事情。

        让我们创建一个Observer,它有一个处理重定向的next 方法和一个只调用nexterror 方法。

        const redirectObserver = {
          next() {
            this.router.navigate([''])
          },
          error() {
            this.next()
          }
        };
        

        现在我们可以通过将其传递给 Observable.subscribe() 来在您的原始示例中使用它

        private initializeCurrentUser() {
          this.userService
            .initializeCurrentUser()
            .subscribe(redirectObserver);
        }
        

        这行得通!当Observable 发出或出错时,将触发对路由器的导航方法的调用。我反对这一点的论点是nexterror 通常是不同的,这种方法隐藏了我们正在打破常规。即使我们真的想以同样的方式处理它们,我们也可以非常明确地表达出来。

        如果只是将重复的逻辑提取到辅助方法中呢?这与您想要做的结果相同,并且可以清楚地显示代码和意图。

        private redirectToHomepage() {
          this.router.navigate(['']);
        }
        
        private initializeCurrentUser() {
          this.userService
            .initializeCurrentUser()
            .subscribe(
              () => this.redirectToHomepage(), //next
              () => this.redirectToHomepage()  //error
            );
        }
        

        现在,如果您想更改重定向的位置或添加额外的逻辑,它只会在一个地方,redirectToHomepage 的定义中,而不是在nexterror 中。我们之前的示例也有这个好处,但是现在我们非常明确,很容易看出我们期望在nexterror 被触发时会出现相同的行为。

        RXJS 可观察示例在这里:https://rxjs-dev.firebaseapp.com/api/index/class/Observable

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-02
          相关资源
          最近更新 更多