rxjs:切换地图后访问原始观测结果

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

切换映射后,如何访问tap运算符中的resultB

奖金问题:
是否有可能避免在这里嵌套,并在单管下将整个流量连环?

< 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
            })
        ))
    ))
}