【问题标题】:What are the advantages/disadvantages of performing operations in pipe() rather than directly in subscribe() method?在 pipe() 而不是直接在 subscribe() 方法中执行操作的优点/缺点是什么?
【发布时间】:2019-12-09 22:37:46
【问题描述】:

我是 Angular 新手,我正在过滤 ID 与 JWT 有效负载中相同的用户。

我可以在 Observable 的 subscribe() 中这样做:

  this.route.data.subscribe((data) => {
      this.users = data.users.filter((u: User) => u.id !== +this.authService.decodedToken.nameid);
  });

我也可以在 pipe() 方法中这样做:

this.route.data
  .pipe(map(data => data.users.filter((u: User) => u.id !== +this.authService.decodedToken.nameid)))
  .subscribe((data) => {
    this.users = data;
  });

解析器代码(可能与问题无关):

  resolve(route: ActivatedRouteSnapshot): Observable<User[]> {
        return this.userService.getUsers().pipe(
            catchError(error => {
                this.alertify.error('Problem retrieving data');
                this.router.navigate(['/home']);
                return of(null);
            })
        );
    }

现在我为什么要使用 pipe() 方法而不是直接在 subscribe() 方法中进行过滤,在这种情况下使用 pipe() 有什么优点或缺点?两者中哪一个是传统的 Angular 方式?

我认为 pipe() 会慢一点,因为它首先映射然后过滤。

【问题讨论】:

  • 在这种情况下,没有任何区别。但是,如果您想通过将此过滤移动到提供数据的服务或解析器中来简化组件的代码,该怎么办?除了使用 pipe() 之外,您别无选择。
  • 性能应该可以忽略不计。假设您有多个订阅者,您要在每个订阅中进行过滤吗?但正如@JBNizet 所说,你的例子太简单了,看不出区别。你不应该忘记取消订阅(或使用 takeUntil/first 管道)。
  • @s.alem 从 ActivatedRoute observables 退订是没有用的。
  • @JBNizet 你是对的。我学到了一些新东西。谢谢。 stackoverflow.com/a/41359138/1784230

标签: angular rxjs observable rxjs6 rxjs-pipeable-operators


【解决方案1】:

现在有了 pipable 操作符,您就可以进行声明式编程了。 如果我们在订阅中做所有事情,就会有一些陷阱

  • 与另一个 observable 合并变得困难。
  • 如果您想从 observable1 中获取值并将其传递给 observable2,您会执行 mergeMap 还是在另一个订阅中订阅(永远不要这样做)。
  • 您的所有逻辑现在都在一个函数中,难以阅读。

当你编写 pipable 操作符时

  1. 每个函数执行一个特定的逻辑。
  2. 关注点分离
  3. 您只需订阅一次(到最终结果)
  4. 代码看起来很整洁

看例子

const obs1$ = of(1,2,3,4,5);
obs1$.pipe(filter(val => val%2 === 0), map(val => val*2).subscribe(finalValue => console.log(value)

在订阅中写下所有这些看起来很糟糕! 希望这会有所帮助

【讨论】:

    【解决方案2】:

    它创建了一个 observable 来发出你想要的值。在 Angular 中,我们经常使用异步管道,因此我们不必管理订阅,因此 map 在创建和观察进入异步管道的数据是我们想要在模板中使用的数据时非常有用

    users$ = this.route.data
      .pipe(map(data => data.users.filter((u: User) => u.id !== +this.authService.decodedToken.nameid)));
    

    并使用异步管道

    <ng-container *ngIf="users$ | async as users">
      {{ users | json }} users here is updated each time users$ emits a value
    </ng-container>
    

    异步管道为我们管理订阅,我们无需担心退订。

    这只是 RxJs 和管道的冰山一角。一旦你对 RxJs 的基础有了很好的理解,你真的应该停止学习 Angular。它会真正改变你构建 Angular 组件的方式。

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      相关资源
      最近更新 更多