iOS Combine 仅当上一个请求完成时才开始新请求
iOS Combine Start new request only if previous has finished
我有网络请求触发 switui 出现的每个最后一个单元格。有时,如果用户向下滚动速度足够快 -> 向上 -> 请求将在第一个完成之前触发。如果没有组合或反应方法,我有完成块和布尔值来处理这个:
public func load() {
guard !isLoadingPosts else { return }
isLoadingPosts = true
postsDataProvider.loadMorePosts { _ in
self.isLoadingPosts = false
}
}
我想知道是否可以使用 combine 更优雅地解决这个问题,而不需要使用 bool 值。例如,仅当上一个已完成时才执行请求?
如果通话正在进行中,您似乎想跳过。
由于您没有分享您可能拥有的任何 Combine 代码,我假设您有一个像这样的发布者返回函数:
func loadMorePosts() -> AnyPublisher<[Post], Error> {
//...
}
然后可以使用subject发起load调用,一个flatMap(maxPublishers:_:)
下游,发布者数量限制为1:
let loadSubject = PassthroughSubject<Void, Never>()
loadSubject
.flatMap(maxPublishers: .max(1)) {
loadMorePosts()
}
.sink(
receiveCompletion: { _ in },
receiveValue: { posts in
// update posts
})
.store(in: &cancellables)
上面的管道订阅了这个主题,但是如果另一个值在 flatMap
准备好接收它之前到达,它就会被简单地丢弃。
那么load
函数就变成了:
func load() {
loadSubject.send(())
}
我有网络请求触发 switui 出现的每个最后一个单元格。有时,如果用户向下滚动速度足够快 -> 向上 -> 请求将在第一个完成之前触发。如果没有组合或反应方法,我有完成块和布尔值来处理这个:
public func load() {
guard !isLoadingPosts else { return }
isLoadingPosts = true
postsDataProvider.loadMorePosts { _ in
self.isLoadingPosts = false
}
}
我想知道是否可以使用 combine 更优雅地解决这个问题,而不需要使用 bool 值。例如,仅当上一个已完成时才执行请求?
如果通话正在进行中,您似乎想跳过。
由于您没有分享您可能拥有的任何 Combine 代码,我假设您有一个像这样的发布者返回函数:
func loadMorePosts() -> AnyPublisher<[Post], Error> {
//...
}
然后可以使用subject发起load调用,一个flatMap(maxPublishers:_:)
下游,发布者数量限制为1:
let loadSubject = PassthroughSubject<Void, Never>()
loadSubject
.flatMap(maxPublishers: .max(1)) {
loadMorePosts()
}
.sink(
receiveCompletion: { _ in },
receiveValue: { posts in
// update posts
})
.store(in: &cancellables)
上面的管道订阅了这个主题,但是如果另一个值在 flatMap
准备好接收它之前到达,它就会被简单地丢弃。
那么load
函数就变成了:
func load() {
loadSubject.send(())
}