我似乎经常遇到这种情况,我需要沿着流链传递数据。换句话说,我的可观察对象取决于一个或多个其他可观察对象的输出。
下面是一个简单示例的3种方法,但没有一种感觉像“ RxJS”方法。有更好的方法吗?
// Method #1 - looks clean, but feels hacky
let firstResponse = null;
performFirstAction().pipe(
tap(_firstResponse => (firstResponse = _firstResponse)),
switchMap(_firstResponse => performSecondAction(_firstResponse)),
switchMap(secondResponse => performThirdAction(firstResponse, secondResponse))
);
// Method #2 - gets ugly real quick as it scales
performFirstAction().pipe(
switchMap(firstResponse =>
performSecondAction(firstResponse).pipe(
map(secondResponse => ({ firstResponse, secondResponse }))
)
),
switchMap(({ firstResponse, secondResponse }) =>
performThirdAction(firstResponse, secondResponse)
)
);
// Method #3 - might as well just use callbacks at this point
performFirstAction().pipe(
switchMap(firstResponse =>
performSecondAction(firstResponse).pipe(
switchMap(secondResponse =>
performThirdAction(firstResponse, secondResponse)
)
)
)
);
答案 0 :(得分:0)
您的情况还有另一种方法
performFirstAction().pipe(
switchMap(first =>
performSecondAction(first).pipe(mergeMap(second=>performThirdAction(first, second)))
)
),
);
基本上,您将first
作为局部变量,因此,如果您有第四个调用,则可以使用类似的模式并将其嵌套。
,如果需要通用模式,可以尝试通过创建高阶函数以返回可观察值来mergeScan
。这里acc
始终是最后一个可观察到的返回值
from([first,first=>second(first),second=>third(second)])
.pipe(mergeScan((acc,currObs)=>currObs(acc),null))
答案 1 :(得分:0)
最干净,最易读的方法是将中间可观察对象存储在其自己的变量中。
const firstResponse$ = performFirstAction();
const secondResponse$ = firstResponse$.pipe(
switchMap(firstResponse => performSecondAction(firstResponse)),
);
const thirdResponse$ = secondResponse$.pipe(
withLatestFrom(firstResponse$),
switchMap((secondResponse, firstResponse) => performThirdAction(firstResponse, secondResponse))
);