ios - ReactiveSwift 中 flatmap 策略之间的差异
问题描述
从响应式 swift 的文档中,我可以了解Flattening
. 可以在此处找到其中的示例。在该部分中,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
start 闭包中调用。因此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
latest:只打印最后一个值,因为每个生产者都在新值进来时被取消;只允许最后一个值运行到完成。
Outer Signal Producer 5.0
Outer Signal Producer 2.0
Outer Signal Producer 1.0
Observer 1.0
请注意,在所有三种情况下,首先为所有值打印“外部信号生产者”消息。这是因为我们给的闭包flatMap
总是在有新值进来时立即运行。但是生成的生产者会根据 flatten 策略启动和取消。
推荐阅读
- javascript - 如何从@ManyToMany 获取数据?
- android - Sqlite 与 Futurebuilder 和 Listview.Builder - 添加新项目后更新列表视图
- android - Nestedscrollview 内的 Viewpager2 包含两个 Fragment,Recyclerview 有问题
- python - 您的企业 Python 包治理方法是什么?
- javascript - 无法使用 Flask 运行 Javascript 验证
- java - BadSqlGrammarException with namedParameterJdbcTemplate 但不是 psql
- android - Android BottomNavigationView 部分隐藏 RecyclerView 中的最后一项
- javascript - 当 jscript 确认并通过 AJAX 调用 PHP 时如何更新 $_SESSION 值
- firebase - Firebase Firestore:将新数组合并到存储在文档中的数组中?
- html - 如何在我已将 grid-auto-flow 设置为 column 的情况下使用 CSS grid 给出多个列