RxJs可观测重复值

RxJs可观测重复值,rxjs,angular2-observables,behaviorsubject,Rxjs,Angular2 Observables,Behaviorsubject,所以我有一个非常直接的场景。一个主题和可观察的。当客户端登录时,我发布成功;当用户注销时,我发布错误 问题在于LoginComponent中的subscribe方法 第一次一切都很好。用户登录我得到一个事件,但在那之后,当用户第二次注销并再次登录时,我得到两个相同的事件,如果用户注销并再次登录,我得到3个重复的事件,依此类推 AuthService.ts public _loggedIn: Subject<LoggedInOrResetPassword> = new Subject(

所以我有一个非常直接的场景。一个主题和可观察的。当客户端登录时,我发布成功;当用户注销时,我发布错误

问题在于LoginComponent中的subscribe方法 第一次一切都很好。用户登录我得到一个事件,但在那之后,当用户第二次注销并再次登录时,我得到两个相同的事件,如果用户注销并再次登录,我得到3个重复的事件,依此类推

AuthService.ts

public _loggedIn: Subject<LoggedInOrResetPassword> = new Subject();
public loggedId: Observable<LoggedInOrResetPassword> = this._loggedIn.asObservable();


obtainAccessToken(){
 // ommitted
 this.httpClient.post(environment.baseUrl + url, null, requestOptions)
                .subscribe(data => {
                  this.saveToken(data);
                  this._loggedIn.next(LoggedInOrResetPassword.createTrue());
                });
  // ommitted
}


private logout(navigateTo?: string){
    this._loggedIn.next(LoggedInOrResetPassword.createFalse());
}

原因是当
LoginComponent
被销毁时,您没有取消订阅

您的代码应该更改如下

首先将实例属性添加到
LoginComponent
以存储订阅,例如

export class LoginComponent implements OnInit, OnDestroy {
  .....
  loginSubscription: Subscription;
  .....
}
然后更改
ngOnInit
,以便将订阅存储在新添加的属性中

ngOnInit() {
    this.loginSubscription = this.authservice.loggedId.subscribe( ( loggedInOrResetPassword: LoggedInOrResetPassword ) => {
    // HERE I GET DUPLICATE VALUES
});
最终添加
ngondestory
,以确保在组件被销毁时取消订阅

ngOnDestroy {
  if (this.loginSubscription) {
    this.loginSubscription.unsubscribe();
  }
}

看看Angular的
async
管道,它是订阅观测值并自动取消订阅的另一种方法。

谢谢。这是否意味着我应该一直取消订阅?请您解释一下这部分“原因是当LoginComponent被销毁时您正在取消订阅。”我恐怕不理解这一点,因为在您演示如何取消订阅之前,我没有取消订阅。如果我不退订,为什么会触发重复事件。谢谢这是个打字错误。正确的回答应该是“原因是您没有退订”。我更正了答案。一般来说,在订阅组件方法中的可观察内容时,您应始终确保在
ngondestory
中有相应的
unsubscribe
,除非您确定组件的销毁与应用程序的关闭一致(例如,与标准AppComponent类似)。除了手动取消订阅,您还可以使用
takeUntil
,如本文所示:
ngOnDestroy {
  if (this.loginSubscription) {
    this.loginSubscription.unsubscribe();
  }
}