Subject.complete()是否取消订阅所有听众?

Wol*_*ang 30 observable rxjs angular

我用这个方法构建了一个简单的确认对话服务(Angular 2):

confirm(body?: string, title?: string): Subject<void> {
    this.confirmation = new Subject<void>();
    // ... show dialog here... "are you sure?"
    return this.confirmation;
}

_onYesClicked() {
  // ... closing the dialog
  this.confirmation.next();
  this.confirmation.complete();
} 

_onNoClicked() {
  // ... closing the dialog
  this.confirmation.complete();
}
Run Code Online (Sandbox Code Playgroud)

用法:

confirmationService.confirm().subscribe(() => alert("CONFIRMED"));
Run Code Online (Sandbox Code Playgroud)

如果有人使用该服务,他会返回一个Subject(这是一个Observable),并且可以"订阅()".点击"是"时调用订阅,因此确认给出了...

这是正确的方法吗?更重要的是...将致电

this.confirmation.complete();
Run Code Online (Sandbox Code Playgroud)

取消订阅订阅的侦听器,从而防止任何延迟引用(内存泄漏)?

mar*_*tin 37

如果你想确保删除所有Observers,你可以在https://github.com/ReactiveX/rxjs/blob/master/src/internal/Subject.ts#L91中自行检查.它调用complete()所有Observers(Observers通常只是实现Observer接口的哑对象)然后设置this.observers.length = 0;.所以答案是肯定的.

你的方法是有效的,它与Angular2经常使用的方法基本相同EventEmitter.你可以改进的一件事是asObservable()在暴露Subjects 时开始使用.这将隐藏您使用Subject底层并返回常规Observable 的事实.这样你就不会让你的用户偶然(或误解)试图打电话next(),complete()或者error()你的用户Subject.

关于内存泄漏,这必须由RxJS处理,因此您不必担心它,如果有问题,作者可能会在您之前注意到它.

另外看看这个:Observable vs Subject和asObservable

  • @JBNizet我认为单击"否"并不一定意味着错误,但这对OP而言不是我的问题. (2认同)
  • @JBNizet没有冒犯,但这只是不好的建议。调用error()指示有效的用户流不是一个好的设计。代码错误旨在指示技术上有问题,而不是指示用户在对话框中拒绝。可以这样考虑:如果用户在询问“您想炸毁世界吗?”的对话框上单击“否”,我想那不是错误。简而言之,错误是针对未处理的代码流而设计的,这将导致程序崩溃,而不是指示在有效用例中接下来要执行的逻辑分支。 (2认同)