我有2个观测值,我想从X中得到一个值,如果它存在,那么从Y得到它。下面的工作对我来说,但我正在寻找一个更简洁的模式。
import {of} from 'rxjs';
import {map, mergeMap} from 'rxjs/operators';
import {getX, getY} from './getXY';
// getX(id: string): Observable<X>; // gets an X asyncronously
// getY(id: string): Observable<Y>; // gets a Y asyncronously
let id = "abc";
// get an X, or a Y if not X, that matches the id
getX(id).pipe(mergeMap((x: X) => {
if (x) {
return of(x);
} else {
return getY(id).pipe(map((y: Y) => {
if (y) {
return y;
}
}));
}
})).subscribe((xy: X | Y) => { ... }
在我看来,of(x)的方向是错误的——也许有一种方法可以有条件地从gety中提取y,而不需要of(x)。
理想情况下,我将编写一个getxy来完成所有这一切,并返回一个可以订阅的可观察的。
我用原始例子和车手的答案创建了一个codepen。注意,当GETX返回“X”时,CARTANGER仍然调用GTEY——这就是为什么我没有把他的答案标记为解决方案的原因。你可以随意用叉子加上你自己的解决方案。
最佳答案
您可以这样实现getXY
函数:
function getXY(id: string /* or whatever */) {
return concat(
getX(id).pipe(filter(x => Boolean(x))),
getY(id).pipe(filter(y => Boolean(y)))
).pipe(take(1));
}
函数的返回类型将被推断为
Observable<X | Y>
,而实现的必要性稍低。使用
concat
将确保getY
返回的可观测值仅在getX
返回的可观测值完成且未发出或发出错误值时才被订阅。