如何为几个 URLSession.DataTaskPublisher 制作串行队列?

问题描述

我有几个 datataskpublisher,它们从不同的应用程序屏幕向服务器执行请求。如何让它们串行运行?

下面是一个粗略的例子

这是一个执行请求和附加逻辑的服务。

class Service {

   var cacheResult: Data?
   var cacnellable: AnyCancellable?
   static let shared = Service()


   func performPost() -> AnyPublisher<Data,URLError> {
      let task = URLSession.shared.dataTaskPublisher(for: URL(string: "postURL")!)
         .map { (data,_) in data}
         .multicast(subject: PassthroughSubject())

      cacnellable = task.erasetoAnyPublisher().sink(
         receiveCompletion: {_ in },receiveValue: { data in
            self.cacheResult = data
         })

      return task.autoconnect().erasetoAnyPublisher()
   }

   func performGet() -> AnyPublisher<Data,URLError> {
      let task = URLSession.shared.dataTaskPublisher(for: URL(string: "getURL")!)
         .map { (data,receiveValue: { data in
            self.cacheResult = data
         })

      return task.autoconnect().erasetoAnyPublisher()
   }

}

这是视图

final class GetVC: UIViewController {

   let service = Service.shared
   var cancellable: AnyCancellable?

   override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(true)
      cancellable = service.performGet()
         .sink(receiveCompletion: {_ in},receiveValue: { data in
                  print("Present data")
               })
   }

}
final class PostVC: UIViewController {

   let service = Service.shared
   var cancellable: AnyCancellable?

   lazy var button: UIButton = {
      let btn = UIButton(primaryAction: UIAction(handler: { _ in
         self.cancellable = self.service.performPost()
            .sink(receiveCompletion: {_ in },receiveValue: { data in
                     print("Some logic")
                  })
      }))
      return btn
   }()
}

我需要请求永远不会并行到达服务器

如果“发布任务”完成,“获取任务”开始

谢谢!

解决方法

我做出了这个决定

class Service {

   var cacheResult: Data?

   var cancellables = Set<AnyCancellable>()

   var taskSubject = PassthroughSubject<AnyPublisher<Data,URLError>,Never>()
   var taskInProcess: Bool = false
   var tasks: [AnyPublisher<Data,URLError>] = [] {
      didSet {
         if !taskInProcess,let firstTask = tasks.first {
            taskInProcess = true
            taskSubject.send(firstTask)
         }
      }
   }
   static let shared = Service()


   init() {

      taskSubject
         .flatMap { $0 }
         .sink(receiveCompletion: { _ in },receiveValue: { _ in
                  self.taskInProcess = false
                  self.tasks.removeFirst()
               })
         .store(in: &cancellables)

   }

   func performPost() -> AnyPublisher<Data,URLError> {
      let task = URLSession.shared.dataTaskPublisher(for: URL(string: url)!)
         .map { (data,_) in data}
         .multicast(subject: PassthroughSubject())

      tasks.append(task.autoconnect().eraseToAnyPublisher())

      return task.eraseToAnyPublisher()
   }

   func performGet() -> AnyPublisher<Data,_) in data}
         .multicast(subject: PassthroughSubject())

      tasks.append(task.autoconnect().eraseToAnyPublisher())

      return task.eraseToAnyPublisher()
   }

}


相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...