我有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返回的可观测值完成且未发出或发出错误值时才被订阅。

09-30 13:37