使用主题值时可观察与订阅

abc*_*bet 4 rxjs angular

我对 Angular 很陌生,据我所知,Subject这是用于多播的标准类。当尝试这个类时,我发现有两种(可能甚至更多)处理其值变化的途径。

  1. Observable直接在组件内使用类型对象

    在这种方法中, anObservable在组件内声明如下:

    foo$ : Observable<boolean>;
    
    Run Code Online (Sandbox Code Playgroud)

    然后使用以下方法在 html 文件中使用:

    <p *ngIf="(foo$ | async) as foo">Bar!</p>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 第二种方法是Subscription在组件内有一个类型对象,该对象分配给某个成员变量:

    s: Subscription;
    foo: boolean;
    
    Run Code Online (Sandbox Code Playgroud)

    其中订阅初始化如下:

    constructor(private fbs: FooBarService) {
        this.s = fbs.fooObservable.subscribe(v => this.foo = v);
        //  this.s.unsubscribe() is called within ngOnDestroy()
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后 html 将使用如下代码:

    <p *ngIf="foo">Bar!</p>
    
    Run Code Online (Sandbox Code Playgroud)

除了个人喜好之外,是否有任何理由更喜欢这些方法中的任何一种?

Rea*_*lar 5

除了个人喜好之外,是否有任何理由更喜欢这些方法中的任何一种?

这类问题不是本文的主题,但给出一般性答案对于社区来说是有价值的。两者之间有足够的区别,值得讨论。

一种方法称为反应式组件,另一种称为有状态组件

反应性成分

视图使用async管道处理来自可观察量的数据的呈现。如果组件仅使用可观察对象和async管道进行表示,则该组件是无状态的,并通过视图自动对更改做出反应。这有助于为模板创造一种干燥的感觉。

这种方法具有以下优点。

  • 不太可能出现“表达式在检查后已更改”错误。
  • 通过可观察量更容易表示服务或存储的外部状态。
  • 使更改通知的使用变得OnPush更加容易。
  • 这种设计方法创建了一个响应速度更快的组件,可以让开发人员以更少的精力对更改做出反应。

这种方法具有以下缺点。

  • data.subscribe(value => this.value = value)当开发人员不理解反应式编程时,他们很可能会编写代码。
  • 当多个可观察量被合并、切换或组合而没有太多解释原因时,源代码可能很难理解。
  • 引入内存泄漏和订阅丢失的风险。
  • 开发人员有时可以在不了解所有副作用的情况下使用运算符。使用mergeMap()代替switchMap()作为示例。
  • 您必须跟踪可观察量的生命周期。
  • IDE 编辑器很难自动完成类型。例如; 将创建一个在大多数 IDE 中属于未知类型的<ng-container *ngIf="data$ | async as data">视图变量数据。
  • 陡峭的学习曲线。RXJS 并不容易掌握。
  • debugger;由于组件没有可调试的状态,因此很难进行调试。
  • 单元测试比较困难。没有组件状态可以断言它是正确的。

有状态组件

当组件具有视图模板中使用的属性时,该组件就是有状态的。组件的内部状态必须更改才能表示视图中的更改,这是Angular 中组件的默认类型。

这种方法具有以下优点。

  • 开发、维护和阅读源代码更加容易。
  • @Input()绑定一开始就是有状态的。
  • IDE 具有更好的组件属性自动完成功能。
  • 具有更容易的学习曲线。无需学习第三方库。
  • debugger;在浏览器中使用更容易,因为您可以看到组件的当前状态。
  • 单元测试更容易。

这种方法具有以下缺点。

  • 当使用服务的外部状态时,最有可能出现“表达式在检查后已更改”错误。
  • subscribe()当您混合可观察量时,源代码会因调用而变得混乱。
  • 您必须手动将反应流转换为组件状态,并编写类似data.subscribe(value => this.data = value).
  • 使用外部可观察量时,变化检测成为一个挑战。
  • 创建响应外部事件和可观察量的响应组件需要更多行代码。

结论

在决定使用两种方法中的哪一种时。我建议从有状态组件开始,然后逐步提高您的反应式组件技能。

根据我的经验,反应式组件是最佳选择,因为它们是可观察流的目的地。这些组件将可观察量组合在一起以创建该数据的响应式视图,并且它们会自动对这些流中的更改做出反应。同时,将数据合并作为目的地更多地是 Angular 中的一种架构设计。所以这是一个更广泛的讨论和主题,但继续学习,你就会到达目的地。