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

问题描述 投票:1回答:2

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

我也在使用rxjs 5.1.0。

我有一个服务,我有一个名为BehaviorSubjectfile$和来自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();
  }

它是否正确。我担心内存泄漏等,我应该以某种方式来自unsubscribingfiles$

我无法取消订阅files$中的ngOndestroy,或者至少我会想要再次连接订阅,但因为它是一个成员变量,这将导致问题。

我每次进入这个组件时都应该加入和取消订阅吗?

angular rxjs angular-services
2个回答
1
投票

Point Nr 1:拥有这样的成员变量感觉很奇怪:

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

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

$$是针对主题和其他交互的Observables,$是针对可以订阅的纯Observables

Point Nr 2:在服务中订阅

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

Point Nr 3:在哪里订阅以及如何订阅?

那么你的服务现在应该提供一个或多个公共可读的observable,它们已经映射/过滤/ ....并准备好订阅。因此,您可以将服务注入您选择的组件(您需要数据的位置)。然后在组件中有两种订阅/取消订阅管理方式。

我不确定这个是否适用于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()}
}

较长的路,但较旧的路

为每个Observable创建一个私有的Subscription实例

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

0
投票

您应该取消订阅您订阅的每个观察者,如果他们没有按时完成(热门和冷观察,您可能想要查看,快速谷歌搜索将为您提供多个博客)。在您自己托管主题的情况下,您绝对应该取消订阅。

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

你取消订阅的方式是正确的一种方法,特别是如果你在一个组件中有多个订阅就是使用像这样的takeUntil:

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.unsubscribe发出时,您将取消订阅所有可观察对象。

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

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

代替

© www.soinside.com 2019 - 2024. All rights reserved.