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(())
}