rxjs-过滤后合并内部可观察物

时间:2018-08-29 15:33:34

标签: rxjs rxjs6

我打电话给响应的后端:

[
  "https://some-url.com/someData1.json",
  "https://some-url.com/someData2.json"
]

每个JSON可以具有以下架构:

{
  "isValid": boolean,
  "data": string
}

我想获取包含isValid设置为true的所有数据的数组

backend.get(url)
    .pipe(
        mergeMap((urls: []) =>
            urls.map((url: string) =>
                backend.get(url)
                    .pipe(
                        filter(response => response.isValid),
                        map(response => response.data)
                    )
            )
        ),
        combineAll()
    )

当两个.json都将“ isValid”设置为true时,我得到了两个数据的数组。 但是,当其中一个将“ isValid”设置为false时,则无法观察到。

我可以使用mergeAll而不是CombineAll,但是随后我会接收到单个数据流而不是所有数据的收集。

还有什么更好的方法可以滤除可观察的东西?

2 个答案:

答案 0 :(得分:1)

正如您所说,内部可观察对象永远不会发出,因为filter不会转发backend.get可观察对象曾经发出的唯一值。在这种情况下,订阅该可观察值的操作员-在您的情况下为combineAll-也将永远不会获得任何值,也永远不会发出自己的值。

我要做的只是通过提供项目功能将过滤和映射移至combineAll

backend.get(url)
    .pipe(
        mergeMap((urls: string[]) =>
            urls.map((url: string) => backend.get(url))
        ),
        combineAll(responses =>
            responses
                .filter(response => response.isValid)
                .map(response => response.data)
        )
    )

看看是否适合您;)

答案 1 :(得分:0)

import { forkJoin, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

interface IRes {
  isValid: boolean;
  data: string;
}

interface IResValid {
  isValid: true;
  data: string;
}

function isValid(data: IRes): data is IResValid {
  return data.isValid;
}

const res1$: Observable<IRes> = backend.get(url1);
const res2$: Observable<IRes> = backend.get(url2);

// When all observables complete, emit the last emitted value from each.
forkJoin([res1$, res2$])
  .pipe(map((results: IRes[]) => results.filter(isValid)))
  .subscribe((results: IResValid[]) => console.log(results));