提问者:小点点

Angular-如何最好地处理服务及其订阅中的主题?


我是rxjs的新手,所以我可能不会像有经验的用户那样使用它。

我也在使用rxjs 5.1.0。

我有一个服务,其中我有一个名为file$行为主题和一个来自file$的可观察对象,称为files

@Injectable()
export class UploadService {
  files$: BehaviorSubject<FileToUpload[]> = new BehaviorSubject([]);
  files: Observable<FileToUpload[]> = this.files$.asObservable();

将这些作为成员变量感觉有点奇怪。

这是正确的还是我能做得更好?

然后在组件onInit中订阅files观察者:

  ngOnInit() {
    this.fileStateSubscription = this.uploadService.files.subscribe((files) => {

yt在ngDestroy上,我正在取消订阅:

  ngOnDestroy() {
    this.fileStateSubscription.unsubscribe();
  }

这是正确的吗?我担心内存泄漏等,我应该以某种方式从文件$中取消订阅吗?

我不能取消订阅ngOn销毁中的文件$,或者至少我需要再次连接订阅,但因为它是一个成员变量,这会导致问题。

每次进入这个组件都应该进行订阅和退订吗?


共2个答案

匿名用户

第1点:有这样的成员变量感觉很奇怪:

我个人更喜欢以下语法,我也在大型项目中看到过它:

export class foo {
  private foo$$ = new BehaviorSubject(false);
  public foo$ = this.foo$$.asObservable();
}

$$用于主体和其他交互可观察对象,$用于纯可观察对象,可以订阅

第2点:在服务内订阅

您的服务将没有ngOnDestroy(只是如果您只为一个组件提供它),因此不仅因为这个原因,而且请不要订阅服务内部的可观察对象。您可以这样做,但因此您需要更深入地了解服务如何工作以及它们在模块中的生命周期。

要点3:在哪里订阅以及如何订阅?

您的服务现在应该提供一个或多个公共可读的可观察对象,它们已经被映射/过滤/……并准备好被订阅。因此,您可以让服务被注入到您选择的组件中(您需要数据的地方)。然后在组件中有两种订阅/unsibscribe管理方式。

我不确定这个是否适用于rxjs 5.5,但让我们试一试:

class foo {

  private subscription = new Subscription();
  constructor(private yourService: YourService) {}
  ngOnInit() {this.subscriptions.add(this.yourService.observable$.subscribe(val => 
  console.log(val)}
  ngOnDestroy() {this.subscriptions.unsibscribe()}
}

更长的路但更古老

为每个观察者创建一个订阅的私有实例

private observableSubscription;
constructor(...){}
ngOnInit() {this.observableSubscription = yourService.observable$.subscribe(...)}
ngOnDestroy() {this.observableSubscription.unsubscribe()}

匿名用户

你应该取消订阅你订阅的每一个可观察的内容,如果它们没有自己完成(热

如果可以的话,拥有这些成员变量,您可能希望为您的可观察文件使用getter。我不太确定约定,但我认为files变量的末尾也应该有一个$。

取消订阅的方式是正确的一种很好的方法,特别是如果您在一个组件中有多个订阅,那就是使用像这样的带直到:

export class YouComponent implements OnInit, OnDestroy {
private unsubscribe$: Subject<void> = new Subject<void>();

constructor(private yourService: YouService) {}

ngOnInit(): void {
    this.yourService.getFiles().pipe(takeUntil(this.unsubscribe)).subscribe(() => // some code)
    this.yourService.getOtherFiles().pipe(takeUntil(this.unsubscribe)).subscribe(() => // some code)
}

ngOnDestroy(): void {
    this.unsubscribe.next();
    this.unsubscribe.complete();
}
}

这样,当this. un订阅发出时,您将取消订阅所有可观察对象。

啊,我刚刚读到你没有管道:我记得你可以用

yourService.getFiles().takeUntil(this.unsubscribe).subscribe()

而是