如何结合可观察的父母和受抚养子女

时间:2018-08-16 07:06:05

标签: rxjs

有一系列不完整的事件对象。每个事件都有乐队。通过订阅事件,您将获得一个具有多个属性的事件,其中包括一个属性“ bands”,用于存储bandId数组。使用这些ID,您可以获得每个频段。 (乐队的流也是连续的。)

问题:最后,您不仅要拥有乐队,而且要拥有带有bandId和完整band对象的完整事件对象。

// This is what I could come up with myself, but it seems pretty ugly.

getEvents().pipe(
    switchMap(event => {
        const band$Array = event.bands.map(bandId => getBand(bandId));
        return combineLatest(of(event), ...band$Array);
    })),
    map(combined => {
        const newEvent = combined[0];
        combined.forEach((x, i) => {
            if (i === 0) return;

            newEvent.bands = {...newEvent.bands, ...x};
        })
    })
)

问题:请帮助我找到一种更清洁的方法(而且我不确定我的尝试是否会产生预期的结果)。

1 个答案:

答案 0 :(得分:2)

接受的答案

getEvents().pipe(
    switchMap(event => {
        const band$Array = event.bands.map(bandId => getBand(bandId));
        return combineLatest(band$Array).pipe(
          map(bandArray => ({bandArray, event}))
        );
    })
)

原始答案

您可能想尝试以下方法

getEvents().pipe(
    switchMap(event => {
        const band$Array = event.bands.map(bandId => getBand(bandId));
        return forkJoin(band$Array).pipe(
          map(bandArray => ({bandArray, event}))
        );
    })
)

此转换返回的Observable发出一个具有2个属性的对象:bandArray保留使用getBand服务检索的波段数组,而event则是返回的Observable发出的对象由getEvents

还请考虑您正在使用switchMap,这意味着getEvents返回的Observable发射后,您将立即切换到最后一个发射,并完成所有可能在运行中的操作。时刻。换句话说,如果执行forkJoin所需的时间长于一次发射和另一次getEvents的发射时间,则可以松开某些事件。

如果您不想丢失任何东西,则最好使用mergeMap而不是switchMap

更新后的答案-可观察范围未完成

在这种情况下,我了解到getBand(bandId)返回一个Observable,它在第一次查询后端时,然后在后端中的band数据更改时,首先发出。 如果这是真的,那么您可以考虑这样的事情

getEvents().pipe(
    switchMap(event => {
        return from(event.bands).pipe(
           switchMap(bandId => getBand(bandId)).pipe(
              map(bandData => ({event, bandData}))
           )
        );
    })
)

此转换会产生一个Observable,它可以在新事件发生时或波段数据更改时发出。