【问题标题】:rxjs condition inside flatmap平面图中的 rxjs 条件
【发布时间】:2017-12-02 16:44:58
【问题描述】:

我想在 flatMap 中有一个条件来检查第一个 observable 返回的内容。如果不满足条件,我想中断并导航到不同的页面。

this.service.getData(id)
  .flatMap((data) => {
    if (!data) {
      return Observable.throw(new NoDataFoundError());
    }
    return Observable.forkJoin(
      this.service.getData2(id2),
      this.service.getData3(id3),
    );
  })
  .subscribe(
    ([data2, data3]) => {
      this.data2= data2;
      this.data3= data3;
    },
    (err) => {
      if (err instanceof NoDataFoundError) {
        this.router.navigate(...);
      }
    }
  );   

目前我正在抛出特定错误并捕获它,但我不喜欢这种解决方案,因为它不是唯一可能抛出错误的代码,并且 if 没有缩放。

我考虑过 filter 或 takeWhile 运算符,但我无法执行重定向。

我还考虑过返回 Observable.of 而不是 throw(在第 4 行),但是我必须在 subscribe 中执行 if ,这也有异味。

【问题讨论】:

  • 代码看起来相当不错。您能否详细说明您的担忧?您可以使用几种不同的模式,但这取决于其他情况。

标签: angular rxjs


【解决方案1】:

您可以在.flatMap 中执行this.router.navigatereturn Observable.empty()。这样,您将拥有一个 if 语句。

.flatMap(data => {
  if (!data) {
    this.router.navigate(...);
    return Observable.empty();
  }
  return (...);
})

但通常Observables 应该是惰性和纯粹的(没有副作用),这将使它们可预测且易于组合。副作用只能由订阅者执行。

在您的具体情况下,似乎正确的解决方案是将这个逻辑放在路由保护中,就像这里描述的那样 - https://stackoverflow.com/a/39162538/3772379

【讨论】:

  • 感谢您的回答,抱歉回复晚了。我不确定 Observable.empty() 因为我必须订阅它。我知道 Observables 应该是纯的,但我认为我的用例很常见。我终于从 canActivate 中获得灵感,但将其改为resolver。感谢您的帮助。
  • 不,这就是诀窍。当您返回 .empty() 时 - 不会发出任何内容,这意味着您不需要在订阅中处理它。
  • 在我的特定问题中,我可以使用 canActivate/resolver 在层次结构中向上移动获取逻辑。当我没有任何提到的机制时,我该如何进行。我能想到的唯一解决方案是在订阅中使用订阅。
猜你喜欢
  • 2019-01-20
  • 2016-11-23
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 2019-09-21
  • 1970-01-01
  • 2018-10-17
  • 2018-12-19
相关资源
最近更新 更多