簡體   English   中英

可觀察的數據服務,未調用訂閱

[英]Observable data service, subscribe not called

我想為用戶對象創建一個反應式存儲。 因此,讓我先描述一下我嘗試過的內容。 我定義了一個簡單的用戶類:

export class User {
  constructor(public $key: string) {}
}

為簡單起見,該類僅包含一個鍵。 我使用Firebase存儲並查詢此存儲,我創建了一個服務類:

export class UserService {

  constructor(private af: AngularFire, private authService: AuthService) {}

  getUser() {
    return this.authService.authInfo$.concatMap(a => this.af.database.object('/users/' + a.uid));
  }
}

getUser()首先獲取用戶ID,並在Firebase數據庫中查詢特定用戶。 但是我不想直接使用該服務。 而是我想擁有一個包含BehaviorSubject的全局存儲,其中包含最新的用戶對象。 因此,讓我們介紹一下商店:

export class UserStore {

  private _user: BehaviorSubject<User> = new BehaviorSubject(null);

  constructor(private userService: UserService) {
    this.userService.getUser().subscribe(
      userJson => {
        this._user.next(new User(userJson.$key, userJson.firstName, userJson.lastName, null, userJson.personalDataSheet));
      },
      err => console.error
    );
  }

  get user() {
    return this._user.asObservable();
  }
}

現在,我在這樣的組件中使用此存儲:

this.userStore.user.subscribe(
  user => console.log(user)
);

而且有效! 用戶已登錄。 但是當我做類似的事情

user: User;
...
this.userStore.user.subscribe(
  user => this.user = user
);

當用戶為null時,subscribe將僅被調用一次。 這是為什么? this.user = user是否創建某種其他訂閱並取消第一個訂閱?

問題是您的BehaviorSubject發出了至少兩個不同的值

  • null —實例化主題時提供的初始值。
  • User實例-Firebase調用返回時發出的值。
  • [可選]修改的User實例-由於Firebase一切都是“實時的”,因此您的主題可能會繼續為當前用戶發出不同的實例(例如,如果用戶注銷,您將獲得一個新值)。

因此,根據您的.subscribe()的執行點,您.subscribe()可能會得到null值。

我會嘗試使用ReplaySubject代替。 一個ReplaySubject 僅在將值顯式推入其中時才開始發出 這意味着您可以擺脫該初始null值,並且只要Firebase沒有返回,該用戶就將不可用(=訂閱將“正在等待”)。

更具體地說,這是我要更改的行:

private _user: ReplaySubject<User> = new ReplaySubject<User>(1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM