我目前有以下代码
func updateItems(_ observable: Observable<ContainingEntity>) -> Observable<ContainingEntity>{
return observable
.concatMap({ (containingEntity) -> Observable<ContainingEntity> in
guard let itemEntity = orderEntity.itemEntity,
itemEntity.name.count == 0 else{
return Observable.just(entity)
}
print("Need to fetch name of item #\(itemEntity.id)")
return RestManager.getDetailOf(item: itemEntity)
.flatMap({ (updatedItemEntity) -> Observable<ContainingEntity> in
var updatedContainingEntity = containingEntity
containingEntity.itemEntity = updatedItemEntity
print("Fetched item name: \(itemEntity.name)")
return Observable.just(containingEntity)
})
})
}
基本上,我需要确保每个 ContainingEntity 的 itemEntity 都有一个名称,如果没有,请用Moya请求。
但我面对两张照片中的以下类型的输出:
意味着我的concatMap中的操作是并行执行的,我不想要因为请求冗余和一些缓存系统我没有在这里显示:我可以有30倍相同的项ID和我不想要30次。
我期待的是:
需要提取项目#2的名称
提取项目名称:Name2
如何解决此问题?非常感谢你的帮助。
更新
我现在正在使用某种简单的缓冲区,这样可以节省需要更新的 ItemEntities ,并将这些项目分配给具有相同项目标识符的下一个 ContainingEntities 。这可以防止Moya多次执行相同的请求。
它完美无缺,但我不太喜欢RX外部这种机制的想法......
答案 0 :(得分:1)
我认为使用Variable
或BehaviorSubject
来控制顺序加载可能会起作用(下面的代码)。
但是您可能想重新考虑加载体系结构,因为使用此代码时,加载时间可能不是最佳的。
限制同时并行请求的数量可能属于其他组件,例如您的网络层。
我没有测试下面的代码,因此它甚至可能无法编译 - 如果有效,请告诉我并接受答案。
func updateItems(_ observable: Observable<ContainingEntity>) -> Observable<ContainingEntity>{
let trigger = BehaviorSubject<Int>(value: 0)
let sequential = Observable.zip(observable, trigger) { return $0.0 }
return sequential
.concatMap({ (containingEntity) -> Observable<ContainingEntity> in
guard let itemEntity = orderEntity.itemEntity,
itemEntity.name.count == 0 else{
return Observable.just(entity)
}
print("Need to fetch name of item #\(itemEntity.id)")
return RestManager.getDetailOf(item: itemEntity)
.flatMap({ (updatedItemEntity) -> Observable<ContainingEntity> in
var updatedContainingEntity = containingEntity
containingEntity.itemEntity = updatedItemEntity
print("Fetched item name: \(itemEntity.name)")
trigger.onNext(0)
return Observable.just(containingEntity)
})
})
}