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