删除仅使用一次的observable的订阅的正确时间

时间:2017-02-04 04:00:32

标签: angular firebase firebase-authentication observable subscription

我有以下登录功能,我只想使用一次登录,反对坐在那里永远听数据。 所以我正在寻找合适的时间来取消订阅方法。 目前,我在得到结果或错误后立即调用取消订阅方法。这是有道理的,因为不再需要观察。

然而......如果我的互联网速度非常慢,会发生什么呢?

代码执行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
    });
}

1 个答案:

答案 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在第一个发出值之后完成,此时订阅者将被自动取消订阅 - 因此不需要显式取消订阅/清理。