【问题标题】:Should rxjs subjects be public in the class?rxjs 主题应该在课堂上公开吗?
【发布时间】:2018-07-05 00:37:44
【问题描述】:

假设我有两个类,您可以在其中观察一些可观察对象。

第一个例子,带有公共主题:

class EventsPub {
   public readonly onEnd = new Subject<void>();
}

第二个例子,带有私有主题和注册方法:

class EventsPriv {
   private readonly endEvent = new Subject<void>();

   public onEnd(cb: () => void): Subscription {
       return this.endEvent.subscribe(cb);
   }
}

第一个示例在某种程度上是不安全的,因为任何人都可以从类外部调用 eventsPub.endEvent.next() 并引入副作用,但是,与示例 2 相比,它允许使用管道,这是一个很大的优势,因为开发人员可以使用 ex。仅使用eventsPub.onEnd.pipe(first()).subscribe(cb) 注册第一个活动。

第二个示例也允许一次性订阅,但需要更多代码和丑陋的取消订阅。

const subscription = eventsPriv.onEnd(() => {
    // logic..
    subscription.unsubscribe()
});

从您的角度来看,最好的方法是什么?或者也许有更好的解决方案?

【问题讨论】:

    标签: javascript angular rxjs reactive-programming rxjs5


    【解决方案1】:

    这很大程度上取决于我的个人喜好,但我会这样做:

    class EventsPriv {
       private readonly endEvent = new Subject<void>();
    
       get endEvent$(): Observable<void> {
          return this.endEvent;
       }
    }
    

    所以在课堂上我将使用endEvent,而我仍然可以使用它,例如。在带有obj.endEvent$ | async 的模板中,从外部看它的行为就像一个 Observable。

    请注意,实际上我返回的是 Subject 的同一个实例。唯一限制外界将其与obj.endEvent$.next() 一起滥用的是Typescript 的类型保护。如果我只使用 JavaScript 或者我将其类型转换为 any,我可以调用 next

    这实际上是公开Subjects 的推荐方式,而不是使用asObservable() 运算符。您会注意到,这在 RxJS 5 内部的任何地方都使用。例如,如果您查看 repeatWhen synopsys:

    public repeatWhen(notifier: function(notifications: Observable): Observable): Observable
    

    您可以看到notifier 函数接收一个 Observable 作为参数(您可以在此处的代码中看到它以及 https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L29)。

    但是,如果您查看调用该函数的代码,您会发现它们实际上传递的是 Subject 而不是 Observablehttps://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114-L115

    这已在 RxJS GitHub 页面上进行了讨论,原因是性能和 Typescript 类型保护就足够了。您可以在这些讨论中阅读更多内容:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 2011-01-25
      • 1970-01-01
      相关资源
      最近更新 更多