3 回答
TA贡献1895条经验 获得超7个赞
switchMap使用类似或 的映射函数mergeMap将一个请求的结果映射到下一个请求。用于forkJoin同时执行多个请求。
所以对于一对多的场景,一般的想法是:
firstRequest().pipe(
switchMap(results => forkJoin(results.map(r => nextRequest(r))))
)
对于你的情况,这将是这样的:
useful = [];
a.get('abc').pipe(
switchMap(abcdatas => forkJoin(getUseFulRequests(abcdatas))),
tap(useful => useful.forEach(u => this.useful.push(u))),
switchMap(useful => useful.length ? c.get('ghi') : EMPTY)
).subscribe((ghidata) => {
completed...
});
function getUseFulRequests(abcdatas: AbcData[]): Observable<SomeVal>[] {
return abcdatas.reduce((acc, abcdata) => {
if (abcdata.exist) {
const request = b.get('def').pipe(
map(defdatas => defdatas.someval)
)
acc.push(request);
}
return acc;
}, []);
}
getUseFulRequests(abcdatas)如果返回一个空数组或 ,这将不会发出任何东西useful.length == 0。
TA贡献1842条经验 获得超21个赞
我认为你正在尝试做的是:
a.get("abc").pipe(
mergeMap((abcdatas) => abcdatas.filter((abcdata) => abcdata.exist)), // let's create a stream with all those useful abcdata
mergeMap(abcdata => b.get('def')), // and for each one of those we perform a b.get request
toArray(), // once all the b.get requests have completed, emit a one value stream with an Array of those values values
concatMap(useful => useful.length ? c.get('ghi') : EMPTY) // let's concat that result with the final request
)
TA贡献1891条经验 获得超3个赞
我相信处理这个问题的最好方法是使用高阶可观察量
考虑下面的代码
useful$ = a.get('abc').pipe(
mergeMap(abcdatas =>
abcdata.exist ? forkJoin(abcdatas.map(abcdata => b.get('def'))) : of(undefined)
),
map(defdatas => defdatas.flat()),
mergeMap(({ length }) => length ? c.get('ghi') : of(undefined))
);
useful$.subscribe({
next: () => {
// Completed...
}
})
我们首先通过管道传输 的结果a.get('abc')并使用 mergeMap 来测试 if abcdata.exist。如果它确实退出,我们forkJoin(abcdatas.map(abcdata => b.get('def')))简单地返回这将组合从 abcdatas 上的 map 函数生成的可观察数组
map(defdatas => defdatas.flat()),将数组转换为单个数组 注意:flat() 是在 ES2019 中引入的
接下来我们解构这个length属性,如果它存在,我们返回我们最终的可观察对象
添加回答
举报