如何返回带有switchMap值的CombineLatest结果?

时间:2020-11-12 15:22:05

标签: rxjs

这基本上就是我所追求的。只是不确定最好的方法来返回开关图中的所有三个组合。

unsubscribes = combineLatest(
      apiCall1,
      apiCall12,
    ).pipe(
      switchMap(([apiCall1Res, apiCall2Res]) => {
        return apiCall3(apiCall1Res.Id)
      })
    ).subscribe(([apiCall1Res, apiCall2Res, apiCall3Res]) => {
      ///Do work
    })

2 个答案:

答案 0 :(得分:3)

如果apiCall3应该在1和2之后:

combineLatest(
  apiCall1,
  apiCall12,
).pipe(
  switchMap(([apiCall1Res, apiCall2Res]) => {
     return apiCall3(apiCall1Res.Id)
        .pipe(map(apiCall3Res => [apiCall1Res, apiCall2Res, apiCall3Res]));
})

有了...,您可以在这里节省一些空间:

combineLatest(
  apiCall1,
  apiCall12,
).pipe(
  switchMap(results => apiCall3(apiCall1Res.Id)
   .pipe(map(apicallResult3 => [...result, apicallResult3])
  )
)

答案 1 :(得分:1)

顺序是正确的,您只需要调整如何对待返回值即可。使用switchMap时,会将可观察序列的输出从接收的类型转换为在switchMap返回中提供的可观察序列的输出类型。因此,您只需要创建一个返回3个值的可观察对象即可。您可以通过将apiCall3的流与其他两个流映射来实现。

我提出一种解决方案,如果您需要更多解决方案,可以对其进行调整以适合您的特定情况。我创建了模拟对象,以使示例直接可执行以进行测试。

您可以在我为您创建的以下stackblitz上看到运行模拟对象的示例:

import { combineLatest, of, timer } from 'rxjs'; 
import { map, switchMap, tap } from 'rxjs/operators';

// Mock objects...
const apiCall1 = timer(1).pipe(map(() => ({id: 1})));
const apiCall2 = timer(2).pipe(map(() => 2));
// apiCall3 mock created bellow on the fly...
let r1, r2; // <-- to save partial results because they are cutted from the flow bellow...

const source = 
combineLatest(
      apiCall1,
      apiCall2,
    ).pipe(
        tap(([apiCall1Res, apiCall2Res]) => { r1 = apiCall1Res; r2 = apiCall2Res;}),
        map(([apiCall1Res, apiCall2Res]) => apiCall1Res.id), // adjust flow to apiCall3
        switchMap((apiCall1ResId) => of(apiCall1ResId).pipe(map(id => id+2))), // <-- apiCall3 mock on the fly
        map(apiCall3Res => [r1, r2, apiCall3Res])
      );
source.subscribe(console.log);

您可以检查输出,因此在订阅观察者代码中会收到3个值。