Оператор expand
решает вашу проблему.
Вот как вы должны его использовать:
import { fromEvent, of, forkJoin, EMPTY } from 'rxjs';
import { expand, delay, map, reduce, last } from 'rxjs/operators';
const DATABASE: Element[] = [
{id:'one', childId: 'three'},
{id:'two', childId: 'four'},
{id:'three', childId: 'five'},
{id:'four', childId: 'six'},
{id:'five', childId: null},
{id:'six', childId: null}
];
mainMethod(['one', 'two']).subscribe(value => {
console.log(value.map(e => e.id));
})
function mainMethod(ids: string[]) {
return forkJoin(ids.map(id => getElementById(id))).pipe(
expand(values => {
if (values.some(el => el.childId)) {
return forkJoin(values
.filter(v => v.childId)
.map(el => getElementById(el.childId))
)
}
return EMPTY;
}),
last() // use this if you want only last emission. Be careful, last throws an error, if no value is passed
// reduce((acc, values) => acc.concat(values), []) // use this if you want everything
)
}
function getElementById(id: string) {
return of(DATABASE.find(el => el.id === id)).pipe(
delay(1000)
)
}
interface Element {id: string, childId: string | null}
Рабочий пример https://stackblitz.com/edit/e499mk