【发布时间】:2020-03-22 02:43:40
【问题描述】:
在Combine 框架中有一个demand 的概念,它允许向publishers 发送背压信号。
假设我有一个简单的发布者:
let numbers = Publishers.Sequence<ClosedRange<Int>, Error>(sequence: 0...100)
我想下载使用这些数字作为参数的某些 URL。我还希望仅在上一次下载完成后才开始下一次下载。
一个天真的方法看起来像这样:
let subscription = numbers.sink(receiveCompletion: { _ in }, receiveValue: {
let url = URL(string: "https://httpbin.org/get?value=\($0)")!
URLSession.shared.dataTask(with: url) {
$0.map { print(String(data: $0, encoding: .utf8)!) }
}.resume()
})
不幸的是,这不能满足在开始下一个下载之前等待上一个下载完成的要求。据我所知,sink 函数将返回AnyCancellable 类型的值,而不是Subscription 类型的值。如果是后者,我们可以在上传完成后根据具体需求调用subscription上的request函数。
控制sink 或任何其他标准组合Subscriber 提供的订阅需求的最佳方法是什么?
【问题讨论】:
-
我个人觉得在操作中处理会更好(以前称为
NSOperation),您可以添加对相同类型的正在进行的操作的依赖。它还将封装大部分代码,并可以返回一个Result,它可以由Future处理 -
我知道还有其他方法可以实现这一点,但我的问题是关于 Combine 及其 API。似乎令人费解的是,对背压的支持被宣传为 Combine 的一个显着特征,但对于一个据说可以通过背压解决的常见需求,并没有简单的解决方案。
标签: swift reactive-programming combine