有一个未完成的事件对象的连续流。每个事件都有乐队。通过订阅事件,您将获得一个具有多个属性的事件,其中一个属性“bands”存储了一个 bandId 数组。使用这些 ID,您可以获得每个频段。(波段流也是连续的。)
问题:最后,您不仅希望拥有乐队,而且还希望拥有一个带有 bandIds 和完整乐队对象的完整事件对象。
// 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};
})
})
)
问题:请帮助我找到一种更简洁的方法来做到这一点(我什至不确定我的尝试是否会产生预期的结果)。
接受的答案
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
.
更新的答案 - Band Observable 未完成
在这种情况下,我理解getBand(bandId)
返回一个 Observable,它在第一次查询后端时首先发出,然后在后端中的带数据更改时发出。如果这是真的,那么你可以考虑这样的事情
getEvents().pipe(
switchMap(event => {
return from(event.bands).pipe(
switchMap(bandId => getBand(bandId)).pipe(
map(bandData => ({event, bandData}))
)
);
})
)
这种转换产生一个 Observable,它在任何新事件发生时或在带区数据发生变化时发出。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句