直接在类上访问主题或使用 getter 有什么区别

c_o*_*goo 0 rxjs typescript angular

假设我有一个公开主题的服务:

import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Injectable()
export class StateService {
  private mySubject = new BehaviorSubject<string>("test");
  mySubject$ = this.mySubject.asObservable();

  constructor() {}

  updateSubject(value: string) {
    this.mySubject.next(value);
  }

  get mySubject2$() {
    return this.mySubject.asObservable();
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的组件中:

import { Component } from "@angular/core";
import { StateService } from "./state.service";

@Component({
  //...
})
export class AppComponent {
  name = this.state.mySubject$;
  name2 = this.state.mySubject2$;

  constructor(private state: StateService) {}
}
Run Code Online (Sandbox Code Playgroud)

在使用访问器返回主题或通过类上的属性直接访问主题方面,除了风格之外还有什么区别吗?

jon*_*rpe 7

有两个区别:

  1. 当您调用get accessor 时,它会调用Subject#asObservable为每个消费者创建一个新的 observable,而该属性是单个 observable。一个 observable 可以有多个订阅者,因此创建多个 observable 的效率稍低。

  2. 当您使用公共属性时,除非您明确标记它,否则readonly消费者可以替换 observable,以便后续访问不会将 observable 链接到实例管理的主题。

在你的情况下,我可能会使用:

import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Injectable()
export class StateService {
  private mySubject = new BehaviorSubject<string>("test");
  readonly mySubject$ = this.mySubject.asObservable();

  updateSubject(value: string) {
    this.mySubject.next(value);
  }
}
Run Code Online (Sandbox Code Playgroud)