可观察 - 地图/连接
Observable - map / concat
我是 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))
)
)
);
我正在针对我所理解的您的问题给出一个通用的解决方案。一般的场景是你有一些操作,你想使用结果来执行另一个操作。最后,您希望发出两者的结果。
在您的特定场景中,第一个操作是一些请求,第二个是映射到另一个操作。
解决方法是使用*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); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.1.0/rxjs.umd.min.js"></script>
因此您的代码可能如下所示:
@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
动作。不过可能会变成意大利面...
我是 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))
)
)
);
我正在针对我所理解的您的问题给出一个通用的解决方案。一般的场景是你有一些操作,你想使用结果来执行另一个操作。最后,您希望发出两者的结果。
在您的特定场景中,第一个操作是一些请求,第二个是映射到另一个操作。
解决方法是使用*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); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.1.0/rxjs.umd.min.js"></script>
因此您的代码可能如下所示:
@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
动作。不过可能会变成意大利面...