4

我知道我不能给出BehaviorSubjectObservable 值,但我需要一种方法来解决这个问题。在应用程序初始化时,我正在获取当前用户(如果存在),我需要提供该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 运算符来解决这个问题,或者其他一些可能性?

提前致谢!

4

3 回答 3

3

我会这样做

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
    })  
}
于 2017-11-21T08:51:02.977 回答
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()为 Subject 的每个新订阅者调用user,您始终可以使用this.getUser().publish()流来代替,以便在新订阅者之间共享。

于 2017-11-21T13:54:31.063 回答
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 调用。

于 2017-11-21T14:37:07.303 回答