Rxjs 如何组合父对象和从属子对象
有一个不完整的事件对象的连续流。每个项目都有乐队。通过订阅事件,您将获得一个具有多个属性的事件,其中有一个属性“bands”,用于存储bandid数组。有了这些ID,你可以得到每个乐队。(波段流也是连续的。) 问题:最后,您不仅希望有波段,还希望有一个带有波段ID和完整波段对象的完整事件对象Rxjs 如何组合父对象和从属子对象,rxjs,Rxjs,有一个不完整的事件对象的连续流。每个项目都有乐队。通过订阅事件,您将获得一个具有多个属性的事件,其中有一个属性“bands”,用于存储bandid数组。有了这些ID,你可以得到每个乐队。(波段流也是连续的。) 问题:最后,您不仅希望有波段,还希望有一个带有波段ID和完整波段对象的完整事件对象 // This is what I could come up with myself, but it seems pretty ugly. getEvents().pipe( switchMap
// 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 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}))
);
})
)
此转换返回的可观察对象发出一个具有两个属性的对象:bandaray
包含使用getBand
服务检索的频带数组和event
由getEvents
返回的可观察对象发出的对象
还要考虑一下,您正在使用switchMap
,这意味着只要getEvents
返回的可观测值发出,您就要切换到最后一次发出,并完成当前可能正在进行的任何操作。换句话说,如果执行forkJoin
所需的时间比一次发射和另一次getEvents
发射所需的时间长,则可能会丢失一些事件
如果您不想丢失任何东西,最好使用mergeMap
而不是switchMap
更新的答案-可观测波段不完整
在这种情况下,我理解getBand(bandId)
返回一个可观测值,该值在第一次查询后端时首先发出,然后在后端中的频带数据更改时发出。
如果这是真的,那么你可以考虑这样的事情
getEvents().pipe(
switchMap(event => {
return from(event.bands).pipe(
switchMap(bandId => getBand(bandId)).pipe(
map(bandData => ({event, bandData}))
)
);
})
)
这种转换产生了一个可观测的信号,它在任何时候发生新事件或波段数据发生变化时都会发出。你让我意识到我的问题中遗漏了一个细节:事件流和波段都没有完成;两者都是持久性的,并接收连续更新。那么,您通过事件对象接收的BandID数组的含义是什么?您需要ID数组来知道哪些频带链接到特定事件。乐队可能仍会获得对其关联事件没有影响的更新。示例:乐队成员可能会改变。我认为用
combinelateest
替换forkJoin
,你的第一个建议正是我想要的。