我创建模型所需的数据是拆分的,只能通过两个 API 请求接收。
第一个 (query.snapshotPublisher()
) 发布者将获得模型的主要部分(包括它的 ID),第二个请求 (getPersonalLikeCount(blogModel: blogModel, userID: "408VYXScmxUtUQB91EoTf0LEMgj2")
) 将获得一些额外的数据并需要 ID(这是一部分这就是为什么我要传递从第一个请求中获得的完整模型的原因。
如果两个请求都是独立的,我将使用 .Zip(other: )
运算符,但由于第二个请求依赖于第一个请求,因此我尝试了以下方法以将模型传递给第二个发布者。
但是使用这种方法,第二个发布者在发送第一个值后被取消,因此即使 getPersonalLikeCount
发布者获得新数据并应该再次发布它们也不会更新模型。
private func getBlogs(from query: Query) -> AnyPublisher<BlogModel, Error> {
let publisher = query.snapshotPublisher()
.flatMap { [self] blogModel -> AnyPublisher<(BlogModel, Int), Never> in
let blogModelPublisher = Just(blogModel)
let likeCountPublisher = getPersonalLikeCount(blogModel: blogModel, userID: "408VYXScmxUtUQB91EoTf0LEMgj2")
let combined = Combine.Publishers.Zip(blogModelPublisher, likeCountPublisher)
return combined.eraseToAnyPublisher()
}
.map { blogModel, personalLikeCount -> BlogModel in
var newModel = blogModel
newModel.personalLikeCount = personalLikeCount
return newModel
}
.eraseToAnyPublisher()
return publisher
}
答案 0 :(得分:0)
从语义上讲,如果您想用一个新请求重新启动一个请求,请使用 map
后跟 switchToLatest
。当且仅当您想并行执行操作时,才使用 flatMap
。奇怪的是,Combine 没有 concatMap,您可以使用它在其他反应式框架中连续执行操作。在你的情况下
doTheFirstThingPublisher
.map { firstValue in
doTheSecondThingPubisher(with: firstValue)
.map { secondValue in (firstValue, secondValue) }
}
.switchToLatest()
.map { firstValue, secondValue in
makeFinalValue(from: firstValue, and: secondValue)
}