ReactiveSwift中平面图策略之间的差异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactiveSwift中平面图策略之间的差异相关的知识,希望对你有一定的参考价值。

从反应式快速文档中,我可以了解Flattening。可以找到其示例here。在Flattening event streams部分中,所有内容都进行了完美讨论。

我对flatmap感到困惑。根据文档,它是Maps each event from self to a new producer, then flattens the resulting producers according to strategy - concat/merge/latest。因此,它应该类似于flattening我猜。

但是,我无法产生类似的行为。例如,考虑以下代码段。如果更改像concat/merge/latest这样的展平策略,则输出不会更改。

let (numbersSignal, numbersObserver) = Signal<String, NoError>.pipe()

numbersSignal.producer.flatMap(.concat) { value -> SignalProducer<String, NoError> in
            print("Outer Signal Producer (value)")
            return SignalProducer<String, NoError> {
                observer, lifetime in
                print("Inner Signal Producer (value)")
                observer.send(value: "Inner")
                observer.sendCompleted()
            }
        }.observe(on: UIScheduler()).startWithValues { result in
           print("Observer (result)")
        }


    numbersObserver.send(value: "A")
    numbersObserver.send(value: "B")
    numbersObserver.send(value: "C")
    numbersObserver.sendCompleted()

输出:

Outer Signal Producer A
Inner Signal Producer A
Observer Inner
Outer Signal Producer B
Inner Signal Producer B
Observer Inner
Outer Signal Producer C
Inner Signal Producer C
Observer Inner

任何人都可以清除吗?

此外,能否提供有关flatmap区分merge, concat, latest效果的任何示例?

答案

这里发生的是,您在flatMap中创建的生产者是同步完成的;您在开始闭包本身内调用sendCompleted。因此,在flatMap中,它正在生产者上调用start,而生产者在对该start的调用甚至返回之前就已完成。这意味着flatMap没有机会应用不同的策略;每个生产者在启动后都立即完成。

[我们可以通过在flatMap中创建一个异步生产器来了解不同策略的行为(请注意,我使用的是Swift和ReactiveSwift的最新版本,所以我使用的是Never而不是NoError):] >

let (numbersSignal, numbersObserver) = Signal<TimeInterval, Never>.pipe()

numbersSignal.producer
    .flatMap(.concat) { value -> SignalProducer<TimeInterval, Never> in
        print("Outer Signal Producer (value)")
        return SignalProducer(value: value).delay(value, on: QueueScheduler())
    }
    .startWithValues { result in
        print("Observer (result)")
    }


numbersObserver.send(value: 5)
numbersObserver.send(value: 2)
numbersObserver.send(value: 1)

在此示例中,我们正在发送TimeInterval值,并且每个创建的生产者都以等于该值的延迟发送给定值。

concat:

每个后续生产者在开始之前都等待上一个生产者完成,因此将按照我们发送它们的确切顺序来打印值。
Outer Signal Producer 5.0
Outer Signal Producer 2.0
Outer Signal Producer 1.0
Observer 5.0
Observer 2.0
Observer 1.0

合并:

一旦我们发送了值,所有生产者将立即启动,因此它们都可以同时运行。因此,将值打印到最小到最大,即延迟最短的生产者首先完成。
Outer Signal Producer 5.0
Outer Signal Producer 2.0
Outer Signal Producer 1.0
Observer 1.0
Observer 2.0
Observer 5.0

最新:

仅打印最后一个值,因为随着新值的出现,每个生产者都会被取消;仅允许最后一个值运行完毕。
Outer Signal Producer 5.0
Outer Signal Producer 2.0
Outer Signal Producer 1.0
Observer 1.0

注意,在所有三种情况下,将首先为所有值打印“外部信号产生器”消息。这是因为我们给flatMap的闭包总是在输入新值时立即运行。但是根据扁平化策略启动和取消生成的生产者。

以上是关于ReactiveSwift中平面图策略之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

JVM(二) GC算法与分代回收策略

垃圾回收策略学习总结

ReactiveSwift源码解析 Lifetime代码实现

ReactiveSwift:使用 MutableProperty 观察托管对象的变化

ReactiveSwift框架

平面/射线交点与点/平面投影的差异