rxjs:切换地图后访问原始观测结果
切换映射后,如何访问tap运算符中的resultB 奖金问题:rxjs:切换地图后访问原始观测结果,rxjs,rxjs6,rxjs-pipeable-operators,switchmap,Rxjs,Rxjs6,Rxjs Pipeable Operators,Switchmap,切换映射后,如何访问tap运算符中的resultB 奖金问题: 是否有可能避免在这里嵌套,并在单管下将整个流量连环? < P>请考虑以下例子: streamA$.pipe( switchMap(resultA => resultA ? streamB1$ : streamB2$), switchMap(resultB => loadData(resultB).pipe(map(x => [resultB, x]))), tap([resultB, data] =&g
是否有可能避免在这里嵌套,并在单管下将整个流量连环? < P>请考虑以下例子:
streamA$.pipe(
switchMap(resultA => resultA ? streamB1$ : streamB2$),
switchMap(resultB => loadData(resultB).pipe(map(x => [resultB, x]))),
tap([resultB, data] => {})
);
这就是如何编写可观察对象以访问resultB并平坦可观察操作符链的方法-
streamA$.pipe(
switchMap(resultA => iif(() => resultA ? streamB1$ : streamB2$),
switchMap(resultB => forkJoin([loadData(resultB), of(resultB)])),
tap(([loadDataResponse, resultB]) => {
//loadDataResponse - This will have response of observable returned by loadData(resultB) method
//resultB - This is resultB
})
);
这里的基本问题是switchMap用于转换值以将特定形状发射到流中。如果resultB值不是该形状的一部分,则链下游的运算符将无权访问该值,因为它们只接收发出的形状 因此,基本上有两种选择: 传递一个包含值的中间形状 使用嵌套管道将两条数据带到同一操作符范围中 到目前为止,建议的解决方案涉及到映射到中间对象。我的首选是使用嵌套管道,因此流经流的数据是有意义的形状。但是,这实际上取决于偏好 使用嵌套管道,您的代码将如下所示:
streamA$.pipe(
switchMap(resultA => {
const streamB$ = resultA ? streamB1$ : streamB2$;
return streamB$.pipe(
switchMap(resultB => loadData(resultB).pipe(
tap(data => {
// you can access resultB here
})
))
);
})
);
注意:您可以使用iif有条件地选择源流:
streamA$.pipe(
switchMap(resultA => iif(()=>resultA, streamB1$, streamB2$).pipe(
switchMap(resultB => loadData(resultB).pipe(
tap(data => {
// you can access resultB here
})
))
))
);
将某些逻辑分解为单独的功能可能会有所帮助:
streamA$.pipe(
switchMap(resultA => doSomeWork(resultA)),
miscOperator1(...),
miscOperator2(...)
);
doSomeWork(result) {
return iif(()=>result, streamB1$, streamB2$).pipe(
switchMap(resultB => loadData(resultB).pipe(
tap(data => {
// you can access resultB here
})
))
))
}
提示:可以在要访问resultB的点击位置访问resultA。为什么?这个问题的答案应该告诉您需要做什么才能访问tap中的resultB。
streamA$.pipe(
switchMap(resultA => doSomeWork(resultA)),
miscOperator1(...),
miscOperator2(...)
);
doSomeWork(result) {
return iif(()=>result, streamB1$, streamB2$).pipe(
switchMap(resultB => loadData(resultB).pipe(
tap(data => {
// you can access resultB here
})
))
))
}