我有一个Observable<EntityId[]>
,可以为每个EntityId获取一个Observable<Entity>
。我想将其转换为Observable<Entity[]>
。以下内容以简单的方式解决了该问题:
idsStream
.Select(ids => ids
.Select(id => StreamEntity(id))
.CombineLatest())
.Switch()
问题在于,每次idsStream发出一些新的ID时,每个实体订阅都将关闭,而新的实体订阅将被打开。我只想关闭EntityId[]
中不再包含的Observable,并为添加的ID打开新的流。
在我看来,应该为此有一个运算符,但我什么也找不到。有谁知道这样的运算符,还是我应该自己编写/实现。如果是这样,以下内容似乎是一个主意
// Only select for new elements and reuses former values
SelectAndKeep: Observable<TIn[]> -> (TIn -> TOut) -> Observable<TOut[]>
// Only subscribes/unsubscribe to new/removed observables
SwitchKeepAndCombineLatest: Observable<Observable<T>[]> -> Observable<T[]>
Observable<EntityId[]> idsStream
Observable<Observable<Entity>[]> entitiesStreamStream =
idsStream.SelectAndKeep(id => StreamEntity(id))
Observable<Entity[]> entitiesStream = entitiesStreamStream
.SwitchKeepAndCombineLatest()
对这种情况有任何想法或经验吗?似乎很通用,因此应该存在一个好的解决方案...
答案 0 :(得分:0)
根据我对您问题的理解,我为您提供此实现:
interface Entity {
id: number;
title: string;
}
const entities: Entity[] = [{id: 1, title: 'foo1'}, {id: 2, title: 'foo2'}, {id: 3, title: 'foo3'}];
const entities$ = of(entities); // Observable of Entity[]
const ids$ = of([1,2], [1,3]); // Observable of ids.
ids$.pipe(mergeMap(ids => {
// Transform collection of id to collection of entity
return entities$.pipe(map((entities) => {
// from whole collection of entity, let keep what is present on ids.
return entities.filter(entity => ids.findIndex(id => entity.id === id) !== -1);
}));
})).subscribe(console.log);
entities$
“可观察”应该是“可热观察”(例如BehaviorSubject),以便始终接收商店中可用的最后一个实体。 mergeMap
并行合并并将ids$
流中的每个新数据映射到按原始id集合过滤的实体集合。