我是否需要填写主题才能进行垃圾回收?

Sea*_*lsh 15 rxjs angular

我遵循Angular组件中的清理模式,如下所示:

class SomeComponent implements OnInit, OnDestroy {
    private destroy$ = new Subject();

    ngOnInit() {
        service.someStream().takeUntil(this.destroy$).subscribe(doSomething);
    }

    ngOnDestroy() {
        this.destroy$.next(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

这具有在组件被销毁时自动取消订阅的好处.

我的问题是:是否引用destroy$无限期地粘贴,因为我没有调用this.destroy$.complete(),或者在收集父类时是否会获得GC?

car*_*ant 16

如果你查看源代码Subject.complete,你会找到答案:

complete() {
  if (this.closed) {
    throw new ObjectUnsubscribedError();
  }
  this.isStopped = true;
  const { observers } = this;
  const len = observers.length;
  const copy = observers.slice();
  for (let i = 0; i < len; i++) {
    copy[i].complete();
  }
  this.observers.length = 0;
}
Run Code Online (Sandbox Code Playgroud)

呼叫complete通知任何观察者,然后清除观察员阵列.除非您有一个观察者/订阅者Subject,但是complete实施中没有任何内容可以影响是否Subject可以进行垃圾收集.

RxJS将通知推送给订阅者.订户不提及可观察者; 反过来说.因此,除非您明确创建了一个订阅者,该订阅者Subject通过闭包或其他机制保存对引用的引用,否则无需调用complete垃圾收集.

  • 在`takeUntil`中的使用很好,因为主题对观察者的引用将通过`takeUntil`启动的取消删除.观察者的参考可能会阻止对象的收集 - 取决于引用观察者的内容 - 但这是一个单独的问题,与是否在该主题上调用"完成"无关. (2认同)