使用 RXJS 有条件地向管道添加操作

Add an operation to pipe conditionally with RXJS

我需要在另一个 API 调用之前有条件地进行一个 API 调用。场景是我有一个表单和两个按钮,保存和完成。当我按下finalize时,如果表单值已经改变,需要先保存。这是我目前的解决方案,但这并不是我真正想要的方式(我不想要一个数组作为结果,我只想要最后一个):

const operations$ = [];

if (form.dirty) {
  operations$.push(myService.saveTheThing(form.value).pipe(...))
}

operations$.push(myService.finalizeTheThing().pipe(...));

combineLatest(operations$).subscribe(() -> { ... });

我不太关心订阅块中的保存操作结果,我宁愿只接收 finalizeTheThing() 返回的一个值,而不是 combineLatest returns。这是我尝试过的另一件事,它类似于我想要的,但显然它不能这样工作:

const stream$ = of(null);

if (form.dirty) {
  stream$.pipe(
    switchMap(() => myService.saveTheThing(form.value).pipe(...))
  );
}

stream$.pipe(
  switchMap(() => myService.finalizeTheThing()
);

stream$.subscribe(myThing => { ... })

当然,如果 saveTheThing() 失败,则不应调用 finalizeTheThing()。这种情况的正确模式是什么?

似乎 switchMap(_ => condition ? doAnotherCall() : of(SOME_DEFAULT_VALUE)) 可以正常工作。简而言之,您 swtichMap 到 "do-nothing" Observable 取决于与 "do-something" 相同类型的条件。这是函数式编程中的常见做法。

其他 - 功能更强大但对新手来说更难正确使用 - 是 higher order observable:你可以有一个 Observable 本身根据一些参数化产生 Observable - 在你的情况,基于你提到的条件。

你可以像下面这样压缩代码

of(form.dirty).pipe(
   switchMap(dirty=>dirty?myService.saveTheThing(form.value):of(true)),
   switchMap(e=>myService.finalizeTheThing())
)