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屬性,如果它存在,我們返回我們最終的可觀察對象
添加回答
舉報