rxjs科目应该在课堂上公开吗?

时间:2018-01-25 17:06:19

标签: javascript angular rxjs reactive-programming rxjs5

假设我有两个类,你可以观察一些可观察的类。

第一个例子,公共主题:

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()
});

从您的角度来看,哪种方式最好?或者可能有更好的解决方案?

1 个答案:

答案 0 :(得分:8)

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

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

这实际上是公开Subject而不是使用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类型保护就足够了。您可以在以下讨论中阅读更多内容: