【问题标题】:Combine - Remove pipeline from container合并 - 从容器中移除管道
【发布时间】:2021-04-16 16:31:17
【问题描述】:

假设以下简化代码-sn-p

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-pipeline 获取所有数据,从该容器中删除此类 URLSession-pipeline 的正确方法是什么?

【问题讨论】:

标签: swift combine


【解决方案1】:

您可以做的一件事是从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 和通过主题的回调来处理多个请求。

【讨论】:

  • 有多个并行调用 loadDataFor(),仅使用一个“主题”变量不是可行的解决方案。在 .sink() 调用中执行的操作更复杂(并且没有竞争条件)。 print 语句只是一个例子。
  • @PatrickBauers,您的问题中缺少的细节是您想在每次请求后做什么?只是为了制作它们,您可以通过它使用主题和send 多个请求。但是,如果每个请求都需要自己的回调或其他东西,那就更复杂了。您提出问题的方式将其简化为仅使用主题即可
  • 好的,我明白了。真正的问题有一个传递给 sink() 调用的闭包。
  • 那么,对于每个请求,您要调用回调吗?有点像这样:loadDataFor(url : URL, callback: (City) -&gt; Void)? @PatrickBauers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 2012-02-16
相关资源
最近更新 更多