赋予BehaviorSubject初始值 - 值为Observable

时间:2017-11-21 08:48:07

标签: angular rxjs observable behaviorsubject

我知道我不能给BehaviorSubject一个Observable值,但我需要一种方法来解决这个问题。在应用程序初始化时,我正在获取当前用户(如果存在),并且我需要为BehaviorSubject提供该潜在值。所以我的服务代码如下所示:

private user = new BehaviorSubject<User>(this.getUser());
public user$ = this.user.asObservable();

getUser(): User {
  // does obviously not work!
  return this.apiService.getUser()
    .map(data => {
      if(data) {
        return data;
      }
      // do something else
    })  
}

那么是否有一些神奇的rxjs运算符来解决这个问题,还是其他一些可能性呢?

提前致谢!

3 个答案:

答案 0 :(得分:1)

我会这样做

private user = new BehaviorSubject<User>(null);
public user$ = this.user.asObservable();

constructor() {
  this.getUser();
}

getUser(): User {
  // does obviously not work!
  return this.apiService.getUser()
    .subscribe(data => {
      if(!!data) {
        this.user.next(data); // <<== added
      }
      // do something else
    })  
}

答案 1 :(得分:0)

如果您执行类似

的操作,该怎么办?
private user = new ReplaySubject<User>(1);
public user$ = this.getUser()
    .first()
    .concat(this.user.asObservable());

getUser(): Observable<User> {
    return this.apiService.getUser()
        .map(data => {
            if(data) {
                return data;
            }
            // do something else
        });
}

这样做只是简化一个observable,它将第一个用户返回主题,以便你可以推送更新。这样您就不需要在任何地方拨打.subscribe

如果您不想为this.getUser()主题的每个新订阅者调用user,则可以始终使用this.getUser().publish()流,以便在新订阅者之间共享

答案 2 :(得分:0)

以下是实现此目的的一种方法:

private user = new BehaviorSubject(null);
user$ = this.user.switchMap(u => (!!u) 
                                    ? Observable.of(u) 
                                    : this.getUser()
                                          .do(nu =>  if (!!nu) this.user.next(nu))
                                          .switchMap(v => (!v) 
                                                          ? Observable.of(v) 
                                                            : Observable.empty()));

只要用户有假名值,这将重新运行api调用。