将初始Observable与Observable进行更改(合并为一个Observable)

时间:2019-12-11 08:40:20

标签: rxjs observable reactive-programming

我有两个观察点。一个将获取初始数据,另一个将对更改做出反应并相应地应用它们:

const initial$: Observable<Report[]>;
const changes$: Observable<ObjectChangeEvent<Report>>;

一些特征是:

  1. initial $必须先完成,然后才能应用更改
  2. changes $可以发出0..n次
  3. 更改后的数组应成为下一个更改发出的基础。这意味着只有第一次更改应适用于初始状态。接下来的更改不应丢弃之前的更改。

我想将两个可观察值合并为一个。我到目前为止最接近的是 combineLatest 运算符。但这与特征2)冲突,因为 changes $ 可能不会发出任何东西。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您的意思是这样吗?

this.result$ = this.changes$.pipe(
  skipUntil(this.initial$),
  // ...
);

或者...

const initial$: Observable<Report[]>;
const changes$: Observable<ObjectChangeEvent<Report>>;

const accumulatedChanges$: Observable<ObjectChangeEvent<Report>[]>;

this.accumulatedChanges$ = this.changes$.pipe(
  scan((acc, curr) => [...acc, curr], []),
  startWith([]),
); // emits [change1], [change1, change2], [change1, change2, change3]....

this.result$ = combineLatest([this.initial$, this.accumulatedChanges$]).pipe(
  // apply all accumulated changes on initial
);

编辑:

OR ....

this.result$ = this.initial$.pipe(
  switchMap(initial => this.changes$.pipe(
    // applyChangeToCurrent is only a placeholder for your semantic to alter the current
    scan((current, change) => applyChangeToCurrent(current, change), initial),
  )),
);

答案 1 :(得分:0)

要满足第一个要求,可以使用last运算符,并与mergeMap组合以切换到changes$可观察的位置,并使用其中的最后一个值initial$。 如果changes$为空,请使用startWith运算符将其用作初始状态。

通常应该看起来像这样:

initial$.pipe(
  last(),
  mergeMap(initialState =>
    changes$.pipe(startWith(initialState))
  )
);