【问题标题】:ReactiveSwift chained SignalProducers will not send completed to downstreamReactiveSwift 链接的 SignalProducers 不会将完成发送到下游
【发布时间】:2019-12-24 03:42:13
【问题描述】:

由于我是响应式编程的新手,我对在 ReactiveSwift 中链接 SignalProducers 有一些初学者的问题。我的目标是创建一个 SignalProducers 链,以测试我的一个流程。在进行 SignalProducer 链接时,我偶然发现了一个障碍。如果我最里面的 SignalProducer 正在调用 sendCompleted 它不会被传播到下游。这是 Playground 中的模拟代码

  private func doSomethingWithString() -> SignalProducer<Int, Error> {
  return SignalProducer<String, Error> {observer, _ in
    observer.send(value: "Hello")
  }.flatMap(.latest, doSomethingWithInt(string:))
}

private func doSomethingWithInt(string: String) -> SignalProducer<Int, Error> {
  return SignalProducer<Int, Error> { observer, _ in
    observer.send(value: 2)
    observer.sendCompleted()
  }
}

func test() -> SignalProducer<Int,Error> {
  return doSomethingWithString()

}
func leGo() {

  test().start { (event) in
    switch event {
    case .completed:
      print("DONE")
    case .value(let value):
      print("WE HAVE A VALUE: \(value)")
    case.interrupted:
      print("INTERRUPTED")
    case .failed(let error):
      print("FAILED \(error)")
    }
  }
}

leGo()

在这个 sn-p 中,值按预期打印“WE HAVE A VALUE 2”,但从不执行完成,因此从不打印“DONE”。 如果有人解释为什么会这样以及如何正确地做到这一点,我将不胜感激。我可以通过在doSomethingWithString 中调用sendCompleted() 使其工作,但由于我的原始流有两个以上的方法,我不想在每个方法中都写它。另外.take(first:1) 是一个对我来说听起来很奇怪的选项,因为我真的不想通过所有链条来拿一件物品。相反,如果可能的话,我想在一个完成的地方终止整个流。

【问题讨论】:

    标签: swift reactive-swift


    【解决方案1】:

    flatMap 的目的是将每个传入的值转换为新的生产者,然后根据某种策略将来自这些内部生产者的值扁平化为单个流。当内部生产者完成时,它不会发送已完成事件,原因很简单,您可以拥有多个内部生产者,如果它在其内部生产者之一完成时完成,您将错过所有其他内部生产者的值。

    所以答案是,如果您希望整个流完成,您的外部生产者必须发送已完成的事件。

    以下是flatMap 常用用法的示例,希望能说明flatMap 为何如此工作:

    let searchResults = searchText
        .flatMap(.latest) { text in
            performSearch(for: text)
        }
    

    searchResults 信号用于在用户每次更改搜索文本时使用新结果进行更新。因此,您希望流完成只是因为其中一项搜索已完成;您想在用户更改文本时启动新搜索并更新结果。

    您可以为 SignalProducer 编写某种辅助初始化程序,它使用 take(first: 1) 在单个值之后自动完成,但更惯用的是让您的所有生产者在完成后正确发送完成事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多