swift - 合并 - 从容器中移除管道
问题描述
假设以下简化的代码片段
import Foundation
import Combine
public class NetworkFetch {
fileprivate var networkPipelines : Set<AnyCancellable> = []
public func loadDataFor(url : URL)
{
URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: City.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
.sink(receiveCompletion: {_ in print("Finish")},
receiveValue: { v in
print("\(c)\n")
}
)
.store(in: &networkPipelines)
}
}
对于 loadDataFor 的每次调用,都会生成一个新的 combine-pipeline 并将其添加到 networkPipelines 容器中。这个容器随着时间的推移而增长。
一旦 URLSession 管道获取所有数据,从该容器中删除此类 URLSession 管道的正确方法是什么?
解决方案
您可以做的一件事是从内部删除您自己的订阅sink
:
但也许更好的方法是订阅PassthroughSubject
一次并通过它发送请求的 URL 和回调:
private let subject = PassthroughSubject<(URL, (City) -> Void)), Never>()
private var c: Set<AnyCancellable> = []
init() {
subject
.flatMap { (url, callback) in
URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: City.self, decoder: JSONDecoder())
.zip(Just(callback).setFailureType(to: Error.self))
}
.sink(receiveCompletion: {_ in print("Finish")},
receiveValue: { (city, callback) in
callback(city)
}
)
.store(in: &c)
}
public func loadDataFor(url : URL, callback: @escaping (City) -> Void) {
subject.send(url, callback)
}
因此,单个订阅可以通过URL
主题发送一对请求和回调来处理多个请求。
推荐阅读
- r - ggplot2中的指数衰减
- python - Numpy数组 - IndexError:数组索引过多
- javascript - 如何将此 json 对象返回为字符串
- r - 如何在换行符处终止我的模式?
- javascript - 如何在 React 中提交表单后消除对输入的关注
- laravel - Laravel 唯一的验证规则,除了不工作
- python - 无法在 windows 的 virtualenv 中安装 psycopg2
- c++ - 为什么下面的代码块给出输出“ZZZ(一些垃圾值)”而不是“ZZ(一些垃圾值)”
- android - 如何在 Firebase 远程配置中编写 OR 规则/条件?
- git - GitVersion 配置不递增