【问题标题】:Side effect network request副作用网络请求
【发布时间】:2021-11-23 09:15:01
【问题描述】:

我从 RestAPI 获取数据,在收到一个值后,我必须发送另一个网络请求,该请求具有重要的延迟并且对第一次获取没有影响。我想使用handleEvents 发布者运算符,但这个在调试部分的 Apple 文档中。如果我使用flatMap,那么我的接收器将等待第二次获取的结果,但它对我的主流没有影响。有没有其他方法可以启动对主流/管道没有影响的网络调用?

示例 1:这个看起来不错,但 handleEvents 在 Apple 文档的调试部分中

    cancellable = URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/1")!)
        .handleEvents(receiveOutput: { _ in
             cancellable2 = URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/10")!)
                .sink(receiveCompletion: { completion in
                    print(completion)
                }, receiveValue: { value in
                    print(value)
                })
        }
        .sink { completion in
            print(completion)
        } receiveValue: { value in
            print(value)
        }

示例 2:这使我的主流等待从 flatMap 恢复的第二个结果,这使我的流等待完成信号

    cancellable = URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/1")!)
        .flatMap { _ in
            URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/10")!)
        }
        .sink { completion in
            print(completion)
        } receiveValue: { value in
            print(value)
        }

【问题讨论】:

  • 我想向您展示您的代码的另一个问题。 -> 如果您的第一次通话失败,您将无法再次手动发出该网络请求。 (但可以重试 - 当用户需要时不要手动)

标签: ios combine


【解决方案1】:

这是其中一种方式。有了这个,即使第一次调用抛出错误,你也可以多次发送第一个请求。

let startFirst = PassthroughSubject<Void, Never>()
  let startSecond = PassthroughSubject<Void, Never>()
  
  let cancellable =
  startFirst
      .flatMap { _ in
          URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/1")!)
          // handle errors
      }
      .sink { completion in
          print(completion)
      } receiveValue: { value in
          print(value)
          startSecond.send(())
      }
  
  let cancellable2 =
  startSecond
      .flatMap({ _ in
          URLSession.shared.dataTaskPublisher(for: .init(string: "http://httpbin.org/delay/10")!)
          // handle errors
      })
      .sink(receiveCompletion: { completion in
          print(completion)
      }, receiveValue: { value in
          print(value)
      })
  
  startFirst.send(()) // start first network request

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多