switchMap 在技术上意味着,切换到另一个 Observable 流。这意味着您无法保留该值,因为您的观察者现在正在观察不同的来源。
有几种方法可以将值从一个流“保留”到另一个流,具体取决于您喜欢哪一种。
1。行为主体
这是最优选的方式,因为BehaviourSubject的目的是保留Observable的值:
//initialize a BehaviourSubject
let v2BSubject = new BehaviourSubject<any>(null);
const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
.switchMap((v1) => someAsync1(v1))
.switchMap((v2) => {
//store your v2 value here!
v2BSubject.next(v2);
return someAsync2(v2)
})
.map((v) => applyToUI(v))
.flatMap((v) => {
//get your v2 values here
let v2Value = v2BSubject.value;
return Observable.concat(Observable.of(action1(v)), Observable.of(action2(true)))
}) //
}
或者您可以将其用作Observable。这样您就可以将其视为可观察的并使用 rxjs 运算符可以提供的任何内容:
.flatMap((v) => {
return Observable.concat(Observable.of(action1(v)), v2BSubject.asObservable())
})
2。使用.map 传播值。
这是相当hacky,但可以完成工作。但是请注意它正在修改流源。如果您在管道中有许多操作,它可能会迅速爆发且难以管理:
const anEpic = ($action: ActionsObservable<MyAction>, store: Store<MyRootStore>) => {
return $action.ofType(ActionTypes.AN_ASYNC_ACTION)
.switchMap((v1) => someAsync1(v1))
.switchMap((v2) => {
someAsync2(v2)
.map(afterSomeAsync2 => {
return {
v1Value: v2,
v2Value: afterSomeAsync2
}
})
})
.map(({v1Value, v2Value}) => {
return applyToUI(v1Value).map(v1 => {
return {
v1Value: v1,
v2Value: v2Value
}
})
})
.flatMap(({v1Value, v2Value}) => {
return Observable.concat(Observable.of(action1(v1Value)), Observable.of(v2Value))
})