conditional-statements - RxJs:如何有条件地链接 BehaviorSubject 的 observable?

标签 conditional-statements rxjs observable chain

我有一个可观察的数据服务 (UserService),它返回当前登录的用户。我跟着这个教程 - https://coryrylan.com/blog/angular-observable-data-services ,它描述了使用 BehaviorSubject 立即返回默认的 currentUser,然后在加载或更改后发出真实的 currentUser。服务基本是这样的...

private _currentUser: BehaviorSubject<User> = new BehaviorSubject(new User());
public currentUser: Observable<User> = this._currentUser.asObservable();

constructor(private http: Http) {}

loadUser() { // app.component onInit and login component call this
  return this.http.get('someapi.com/getcurrentuser')
  .map(response => <User>this.extractData(response))
  .do(
    (user) => {
      this.dataStore.currentUser = user;
      this._currentUser.next(Object.assign(new User(), this.dataStore).currentUser);
    },
    (error) => this.handleError(error)
  )
  .catch(error -> this.handleError(error));
}

每当用户按 F5 重新加载整个 spa 时,我都会遇到问题。当消费组件订阅 UserService 上的 currentUser 时,它会立即收到一个默认用户,而 UserService 则等待 api 调用以接收实际用户。 api 调用完成的那一刻,真正的用户是由 UserService 发出的,所有订阅者都得到了真正的用户。然而,BehaviorSubject 发出的第一个值是默认值,它的 id 始终为“undefined”,因此我们还不能进行下一个 api 调用。事实上,当真正的用户通过并且我可以使用 user.id 进行有效调用时,链接订阅永远不会发生,我也不会从响应中获取值。

我知道我在做一些愚蠢的事情,但我还没有弄清楚到底是什么。我只是偶然发现了 concatMap,但我不确定如何使用它。当我追求这一点时,我想知道为什么下面的代码不起作用。我特别想知道为什么订阅永远不会触发,即使在真正的用户进来之后,也只是为了帮助我的新手理解 Observables。
this.userService.currentUser
  .flatMap((user) => {
    this.user = user;
    // Need to NOT call this if the user does not have an id!!!
    this.someOtherService.getSomethingElse(user.id); // user.id is always undefined the first time
  })
  .subscribe((somethingElse) => {
    // This never gets called, even after the real user is emitted by the UserService 
    // and I see the getSomethingElse() call above get executed with a valid user.id
    this.somethingElse = somethingElse;
  });

最佳答案

如果您想忽略没有 id 的用户实例,使用 filter operator :

import 'rxjs/add/operator/filter';

this.userService.currentUser
  .filter((user) => Boolean(user.id))
  .flatMap((user) => {
    this.user = user;
    this.someOtherService.getSomethingElse(user.id);
  })
  .subscribe((somethingElse) => {
    this.somethingElse = somethingElse;
  });

关于“为什么订阅永远不会触发”,可能是由于未定义 id 引起的错误。 .您只通过一个 next函数到 subscribe ,因此将无法处理任何错误。如果发生错误,observable 将终止并取消订阅任何订阅者 - 因为这就是 observables 的行为 - 所以任何具有定义 id 的后续用户不会收到属性。

关于conditional-statements - RxJs:如何有条件地链接 BehaviorSubject 的 observable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43011034/

相关文章:

angular - 可观察类型错误 : cannot read property of undefined

javascript - knockout : How to use checked binding with observable array of whole objects, 但比较个别属性?

java - 随着模型内部状态的变化更新 java GUI

javascript - 如何模拟 RxJs Observable Websocket 进行单元测试

Java:数学条件

javascript - 使用不同的参数调用 javascript 函数,具体取决于我所在的页面

mysql - 如果 Left Join 返回行,条件 Where 子句?

angular - 如何有条件地更新 Angular 路由解析器数据?

angular - 简单的 Angular2 Reactive Form 控件启用状态更改

python - 有条件填充数据框 pandas