我有以下登录功能,我只想使用一次登录,反对坐在那里永远听数据。 所以我正在寻找合适的时间来取消订阅方法。 目前,我在得到结果或错误后立即调用取消订阅方法。这是有道理的,因为不再需要观察。
然而......如果我的互联网速度非常慢,会发生什么呢?
代码执行observable并等待数据从firebase返回(为了论证,请说1分钟)。 在这段等待期间,如果有人在firebase中修改了这个条目,我相信firebase会想,"嘿,有人还在听,并且有变化,所以我最好向这个人发布更新"
所以在这一点上,我将等待两组数据回来,第一组和更新后的数据。
那么我是否会从控制台打印出两个数据,或者这不会发生?
onLogin() {
// loginWithEmailPassword returns firebase.promise<AuthState>
this.userService.loginWithEmailPassword(this.loginForm.value.email, this.loginForm.value.password)
.then(data => {
// if the user is logged in, go and retreive user information
// getUserInformation returns Observable<any>
let subscription_getUserInformation = this.userService.getUserInformation(data.uid)
.subscribe(result => {
// user information received
console.log(result)
// remove Subscription
subscription_getUserInformation.unsubscribe();
}, error => {
// something went wrong
subscription_getUserInformation.unsubscribe();
})
}, error => {
// something went wrong
});
}
答案 0 :(得分:2)
您的订阅者只会收到一次通知,因为您取消了订阅者的next
功能。
但是,代码比它需要的更复杂,因为只要observable完成或错误,observable的订阅者就会自动取消订阅。
如果您只想要一个可观察的第一个发射值,您可以使用first
运算符(与take(1)
等效):
import 'rxjs/add/operator/first';
onLogin() {
this.userService
.loginWithEmailPassword(
this.loginForm.value.email,
this.loginForm.value.password
)
.then(data => this.userService
.getUserInformation(data.uid)
.first()
.subscribe(
result => { console.log(result); },
error => { console.log(error); }
)
)
.catch(error => { console.log(error); });
}
使用该运算符将确保组合的observable在第一个发出值之后完成,此时订阅者将被自动取消订阅 - 因此不需要显式取消订阅/清理。