【问题标题】:Difference in combineLatest behaviour Signal v SignalProducer (ReactiveCocoa 4)combineLatest 行为 Signal v SignalProducer (ReactiveCocoa 4) 的差异
【发布时间】:2016-03-11 22:10:15
【问题描述】:

我目前正在运行基本运算符,并遇到了 combineLatest 运算符的行为差异。我不确定这是错误还是我未能理解 Signals 和 SignalProducers 之间的差异。

let (numbersSig, numbersOb) = Signal<Int, NoError>.pipe()
let (lettersSig, lettersOb) = Signal<String, NoError>.pipe()
let signal = combineLatest(numbersSig, lettersSig)
signal.observeNext({value in print(value)})

numbersOb.sendNext(1)
lettersOb.sendNext("A")
lettersOb.sendNext("B")

产生: (1,“A”) (1, "B")

但是,如果我使用 SignalProducers 编写我认为等效的代码:

let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
    for v in [1] { observer.sendNext(v) }
}

let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
    for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
}

let combinedProducer = combineLatest(numberProducer, letterProducer)
combinedProducer.on(next: {value in print(value) }).start()

输出: (1, "D")

我故意将observer.sendCompleted() 排除在SignalProducers 之外,因为我认为这是负责任的,但事实并非如此。我错过了什么?

【问题讨论】:

    标签: swift reactive-cocoa-4


    【解决方案1】:

    是的,这看起来确实是一个错误。您介意在 Github 存储库上打开一个问题,以便我们在那里查看吗?更好的是,如果你能打开一个测试失败的 PR,那就太棒了! :)

    我会检查一些可能是解决方法的问题:如果您使用 startWithNext 而不是 on + start,您会得到相同的结果吗?

    【讨论】:

      【解决方案2】:

      感谢 NachoSoto 的建议。我尝试了您建议的替代方法,并且输出没有改变。当我在 Github 存储库上发布此问题时,我收到了来自 Aromas (Brian Thomas) 的以下答案:

      在 combinedProducer 上调用 start 处理在 内部字母和数字生成器(具体参见 liftRight in SignalProducer.swift,当 otherProducer.startWithSignal 的时候 闭包返回它将运行您的 sendNext 代码)。因为他们是 同步字母生产者只是“下一个”它的所有值 在数字生产者开始返回值之前。你可以测试这个 通过在生产者的 combineLatest 方法调用中反转它们 例子。如果您想获得第一个“推送值”行为 试一试

      let (numbersSig, numbersSink) = Signal<Int, NSError>.pipe()
      let (lettersSig, lettersSink) = Signal<String, NSError>.pipe()
      let numberProducer = SignalProducer(signal: numbersSig)
      let letterProducer = SignalProducer(signal: lettersSig)
      
      let combinedProducer = combineLatest(numberProducer, letterProducer)
      combinedProducer.on(next: {value in print(value) }).start()
      
      lettersSink.sendNext("A")
      numbersSink.sendNext(1)
      lettersSink.sendNext("B")
      numbersSink.sendNext(2)
      lettersSink.sendNext("C")
      

      我尝试按照他的建议反转 numberProducer 和 letterProducer,输出确实与我最初使用信号时遇到的一样,即

      let numberProducer = SignalProducer<Int, NoError> { (observer, disposable) in
          for v in [1] { observer.sendNext(v) }
      }
      
      let letterProducer = SignalProducer<String, NoError> { (observer, disposable) in
          for v in ["A", "B", "C", "D"] { observer.sendNext(v) }
      }
      
      let combinedProducer = combineLatest(letterProducer, numberProducer)
      combinedProducer.startWithNext {value in print(value)}
      

      产生: (“一”,1) (“乙”,1) (“C”,1) ("D", 1)

      您仍然认为这是错误还是实现行为?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-19
        • 2015-09-02
        • 2016-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-12
        相关资源
        最近更新 更多