rxjs科目应该在课堂上公开吗? [英] Should rxjs subjects be public in the class?

查看:102
本文介绍了rxjs科目应该在课堂上公开吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两个课程,你可以观察一些观察者。

Let's say I have two classes, where you can observe over some observables.

第一个例子,公共主题:

First example, with public subject:

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

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

Second example, with private subject and registering method:

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())注册第一个事件.subsubbe(cb)

The first example is somehow unsafe because anyone can call eventsPub.endEvent.next() from outside the class and introduce side effects, however, comparing to example 2 It allows for pipes, which is a big plus since developers can for ex. register only for the first event with eventsPub.onEnd.pipe(first()).subscribe(cb).

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

The second example also allows for one-time subscription but requires more code and ugly unsubscribing.

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

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

From your point of view, which is the best way to go? Or maybe there is a better solution?

推荐答案

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

This is based a lot on my personal preference but I'd do it like this:

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

   get endEvent$(): Observable<void> {
      return this.endEvent;
   }
}

所以在课堂上我会用 endEvent 虽然我仍然可以使用它,例如。在 obj.endEvent $ |的模板中async 并且从外部看起来就像一个Observable。

So inside the class I'll use endEvent while I can still use it eg. in a template with obj.endEvent$ | async and from the outside it behaves like an Observable.

注意,实际上我正在返回<$ c $的同一个实例C>主题。限制外部世界滥用 obj.endEvent $ .next()的唯一因素是Typescript的类型保护。如果我只是使用JavaScript或者我将其类型化为任何我可以调用 next

Note, that in fact I'm returning the same instance of Subject. The only thing that restricts the outside world from misusing it with obj.endEvent$.next() are Typescript's type guards. If I was using just JavaScript or if I typecasted it to any I could call next.

这实际上是推荐的曝光主题的方式,而不是使用 asObservable()运营商。您可以注意到这在RxJS 5内部随处使用。例如,如果您查看 repeatWhen synopsys:

This is actually the recommended way of exposing Subjects instead of using the asObservable() operator. You can notice that this is used everywhere internally in RxJS 5. For example if you look at repeatWhen synopsys:

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

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

You can see that the notifier function receives an Observable as a parameter (you can see it in the code here as well https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L29).

但是如果你查看调用函数的代码,你会发现它们实际上正在通过主题而不是 Observable https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114 -L115

But if you look into the code where the function is called you'll see they are in fact passing a Subject and not an Observable: https://github.com/ReactiveX/rxjs/blob/5.5.6/src/operators/repeatWhen.ts#L114-L115.

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

This has been discussed on RxJS GitHub page and reasons for this are performance and that the Typescript type guards are sufficient. You can read more in these discussions:

https://github.com/ReactiveX/rxjs/issues/2391

这篇关于rxjs科目应该在课堂上公开吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆