【问题标题】:Observable - map / concat可观察的 - 地图/连接
【发布时间】:2018-05-14 14:41:10
【问题描述】:

我是 Observables 的新手。我有以下效果。

我希望在调度 SunriseSunsetAction 之前调度 PositionUpdateAction 或 PositionFailedAction。

发生的情况是我将 getCurrentPosition() 的结果传递到结果变量中的最后一个映射中,并且调度了 SunriseSunsetAction。 PositionUpdateAction 或 PositionFailedAction 均未调度。

我假设我想以某种方式使用 concat。我一直在尝试各种事情但没有成功。

任何帮助将不胜感激。

@Effect()
  position$: Observable<Action> = this.actions$.pipe(
    ofType(ActionType.GetPosition),
    mergeMap(() =>
      fromPromise(this.geo.getCurrentPosition()).pipe(
        map(value => new UiActions.PositionUpdateAction(value)),
        catchError((err) => {
          return of(new UiActions.PositionFailedAction(err));
        })
      ).map(result =>
        new UiActions.SunriseSunsetAction(this.sun.calculateSunriseSunsetWindows(result.payload.lat, result.payload.long))
      )
    )
  );

【问题讨论】:

  • 因此,如果失败,您希望同时查看PositionFailedActionSunriseSunsetAction
  • 其实很好,如果它失败了,我不希望调度 SunriseSunsetAction
  • 好的,我对答案中的运算符进行了重新排序,以便在创建第二个操作之后进行捕获。

标签: typescript observable ngrx ngrx-store ngrx-effects


【解决方案1】:

我正在为我理解您的问题提供一个通用的解决方案。一般的场景是你有一些操作,你想使用结果来执行另一个操作。最后,您希望发出两者的结果。

在您的特定场景中,第一个操作是一些请求,第二个是映射到另一个操作。

解决方案是使用*Map(...) (switchMap, mergeMap, ...) 使用第一个操作的结果来执行第二个。您可以使用concat 按您选择的顺序发出两个结果,而不是直接从第二个返回可观察对象。这是一个通用示例:

const { of, concat } = rxjs;
const { flatMap } = rxjs.operators;

of(1).pipe(
  flatMap((x) => concat(of(x), of(2)))
).subscribe((x) => { console.log(x); })
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.1.0/rxjs.umd.min.js"&gt;&lt;/script&gt;

所以你的代码可能看起来像这样:

@Effect()
position$: Observable<Action> = this.actions$.pipe(
  ofType(ActionType.GetPosition),
  mergeMap(() =>
    fromPromise(this.geo.getCurrentPosition()).pipe(
      map(value => new UiActions.PositionUpdateAction(value)),
      flatMap((x) => concat(
        of(x),
        new UiActions.SunriseSunsetAction(this.sun.calculateSunriseSunsetWindows(result.payload.lat, result.payload.long))
      )),
      catchError((err) => {
        return of(new UiActions.PositionFailedAction(err));
      })
    )
  )
);

由于您正在使用效果,另一种解决方案是设置另一个效果来侦听PositionUpdateAction 操作。不过可能会变成意大利面……

【讨论】:

  • 谢谢你,这对我帮助很大!
  • @brent 太好了!好吧,如果它回答了您的问题,那么您可以检查答案旁边的复选标记以接受它,以便其他人知道它回答了您的问题。如果没有,请告诉我您是否需要进一步的帮助。
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多