删除仅使用一次的 observable 订阅的正确时间
The right time to remove subscription for observable that is only used once
我有以下登录功能,我只想使用一次登录,而不是永远坐在那里监听数据。
所以我正在寻找合适的时间调用取消订阅方法。
目前,我在得到结果或错误后立即调用取消订阅方法。这是有道理的,因为不再需要 observable。
但是...如果我的网速非常慢会发生什么,这就是会发生什么。
代码执行 observable 并等待数据从 firebase 返回(为了论证,说 1 分钟)。
在这个等待期间,假设有人在firebase中修改了这个条目,我相信firebase会认为,"hey someone is still listening and there is a change, so I better emmit the update to this person"
所以在这一点上,我会等待两组数据回来,第一个和更新的。
那么我会从控制台打印出两个数据还是不会发生这种情况?
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
});
}
您的订阅者只会收到一次通知,因为您正在订阅者的 next
功能中取消订阅。
但是,代码比它需要的更复杂,因为只要可观察对象完成或出错,订阅者就会自动取消订阅。
如果你只想要一个可观察对象的第一个发射值,你可以使用 first
operator (which is equivalient to 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); });
}
使用该运算符将确保组合的可观察对象在第一个发出值后完成,此时订阅者将自动取消订阅 - 因此不需要显式 unsubscription/clean up。
我有以下登录功能,我只想使用一次登录,而不是永远坐在那里监听数据。 所以我正在寻找合适的时间调用取消订阅方法。 目前,我在得到结果或错误后立即调用取消订阅方法。这是有道理的,因为不再需要 observable。
但是...如果我的网速非常慢会发生什么,这就是会发生什么。
代码执行 observable 并等待数据从 firebase 返回(为了论证,说 1 分钟)。 在这个等待期间,假设有人在firebase中修改了这个条目,我相信firebase会认为,"hey someone is still listening and there is a change, so I better emmit the update to this person"
所以在这一点上,我会等待两组数据回来,第一个和更新的。
那么我会从控制台打印出两个数据还是不会发生这种情况?
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
});
}
您的订阅者只会收到一次通知,因为您正在订阅者的 next
功能中取消订阅。
但是,代码比它需要的更复杂,因为只要可观察对象完成或出错,订阅者就会自动取消订阅。
如果你只想要一个可观察对象的第一个发射值,你可以使用 first
operator (which is equivalient to 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); });
}
使用该运算符将确保组合的可观察对象在第一个发出值后完成,此时订阅者将自动取消订阅 - 因此不需要显式 unsubscription/clean up。