asObservable 主题的缺点

Downsides of subjects to asObservable

嗨,我真的很质疑对主题调用“asObserveable()”的用法。

在我看来,它会产生大量不必要的开销。 在我看来,阻止像“next()”或“complete()”这样的调用是无用的。

你能给我一个你应该这样做的好理由吗?

比较一下这两个

  1. 没有
export class TestService {
     public get test$(): Observable<test> {
        return this.test$.asObservable();
     }
    
      public get test2$(): Observable<test> {
        return this.test2$.asObservable();
      }
    
      public get test3$(): Observable<test3> {
        return this.test3$.asObservable();
      }
    
      public get test4$(): Observable<test4> {
        return this.test4$.asObservable();
      }
    
      private readonly _test1$ = new ReplaySubject<test1>(1);
      private readonly _test2$ = new ReplaySubject<test2>(1);
      private readonly _test3$ = new ReplaySubject<test3>(1);
      private readonly _test4$ = new ReplaySubject<test4>(1);
 }

  1. 没有
 export class TestService {  
      public readonly test1$ = new ReplaySubject<test1>(1);
      public readonly test2$ = new ReplaySubject<test2>(1);
      public readonly test3$ = new ReplaySubject<test3>(1);
      public readonly test4$ = new ReplaySubject<test4>(1);
}

我可以给个很好的理由。假设,你想根据特定的动作发出一些事件 execCompleted$。这是它的实现方式

export class TestService {
 private readonly execCompleted$ = new Subject<string>();

 public async makeServerCall(userData){
   const resp = await this.http.post('...').toPromise();
   this.execCompleted$.next(resp.data.id);
   return resp;
 }

 public getUpdatedId(){
   this.execCompleted$.asObservable();
 }

}

现在,此服务由两个组件使用 -> AdminUserInfo

Admin组件可以使用makeServerCall()更新部分用户信息,更新部分用户数据。此事件必须由 UserInfoComponent 捕获,以便它可以侦听和更新信息(一旦执行了某些更新)。

通过使用 getUpdatedId() 公开 Subject,您限制了任何其他组件错误地在 execCompleted$ 上发送 next() 事件。只有在调用 makeServerCall(userData) 时才会触发此主题。

这只是一个简单的例子。还有更复杂的案例,但都有相同的潜在意图。

To not allow unwanted events to be emitted or cancelled. Only the intended source should so that.

这是编程中的标准做法,您希望对其他人可以扩展的内容和不能扩展的内容进行一些限制。有点像open-closed principal.

主题 asObservable 的缺点

一些样板代码。别的不多了。

In my view it creates a big unnecessary overhead.

你量过吗? Subjects 扩展了 Observables,它所做的只是创建一个浅拷贝。如果您发现差异大于方差(实际上不可测量)的应用程序,我会感到惊讶。

主题 asObservable 的优点

更简洁的架构意味着更容易找到错误and/or更容易从一开始就阻止错误的产生。

封装是干净架构的基础之一。因为封装从其他部分隐藏了我们程序的某些部分,所以它使每个部分更容易推理。因此更容易理解、编写、扩展和维护。

如果架构良好的系统出现错误,表面积就会小得多。

一般来说,这些决策的好处往往会在更大的项目和更大的团队中为人所知。如果您正在家里编写一个业余爱好项目,或者您自己或一个小团队正在制作一个最小可行的产品,那么放弃过度计划以加快速度可能是有意义的。这样的项目一旦成长,可能需要 re-write/overhaul,但到那时,额外的努力将是值得的。

Subject 的 asObservable 的替代方案

如果你有相对严格的静态类型检查器设置(TypeScript、Elm、PureScript、ClojureScript 等),那么你可以 return Subject 作为 Observable 而无需对 运行类型的时间表示。

您获得零 运行 时间成本的封装。