未执行ReactiveSwift管道平面映射体转换
我有以下管道设置,由于某种原因我无法理解,跳过了第二个平面图:未执行ReactiveSwift管道平面映射体转换,swift,flatmap,reactive-swift,Swift,Flatmap,Reactive Swift,我有以下管道设置,由于某种原因我无法理解,跳过了第二个平面图: func letsDoThis() -> SignalProducer<(), MyError> { let logError: (MyError) -> Void = { error in print("Error: \(error); \((error as NSError).userInfo)") } return upload(uploa
func letsDoThis() -> SignalProducer<(), MyError> {
let logError: (MyError) -> Void = { error in
print("Error: \(error); \((error as NSError).userInfo)")
}
return upload(uploads) // returns: SignalProducer<Signal<(), MyError>.Event, Never>
.collect() // SignalProducer<[Signal<(), MyError>.Event], Never>
.flatMap(.merge, { [uploadContext] values -> SignalProducer<[Signal<(), MyError>.Event], MyError> in
return context.saveSignal() // SignalProducer<(), NSError>
.map { values } // SignalProducer<[Signal<(), MyError>.Event], NSError>
.mapError { MyError.saveFailed(error: $0) } // SignalProducer<[Signal<(), MyError>.Event], MyError>
})
.flatMap(.merge, { values -> SignalProducer<(), MyError> in
if let error = values.first(where: { $0.error != nil })?.error {
return SignalProducer(error: error)
} else {
return SignalProducer(value: ())
}
})
.on(failed: logError)
}
编辑3:我发现问题是由于我的方法saveSignal
发送sendCompleted
extension NSManagedObjectContext {
func saveSignal() -> SignalProducer<(), NSError> {
return SignalProducer { observer, disposable in
self.perform {
do {
try self.save()
observer.sendCompleted()
}
catch {
observer.send(error: error as NSError)
}
}
}
}
扩展NSManagedObjectContext{
func saveSignal()->SignalProducer{
返回信号发生器{观察者,可在
自我表演{
做{
试试self.save()
observer.sendCompleted()
}
抓住{
发送(错误:错误为NSError)
}
}
}
}
发送completed是有意义的,所以我无法更改。有什么方法可以更改flatMap以仍然执行我打算执行的操作吗?我认为第二个
flatMap
从未执行的原因是saveSignal
从未发送值;它只是以completed
事件或error
事件结束。这意味着map
将永远不会被调用,也不会向第二个flatMap
传递任何值。您可以通过执行以下操作来修复它:
context.saveSignal()
.mapError { MyError.saveFailed(error: $0) }
.then(SignalProducer(value: values))
而不是使用
映射
(因为没有要映射的值,所以它不起任何作用),您只需创建一个新的生产者,在saveSignal
成功完成后发送值
。能否更详细地解释您正在尝试执行的操作?是否要等到所有上载完成后再保存托管对象上下文,还是每次上载完成后都要保存?是否仍要继续如果上传失败要保存吗?感谢@jjoelson的回答,我想在所有上传完成后保存,即使其中一些上传失败。这两个平面图的展平策略在这种情况下有什么不同吗?最新的、合并的、concat的似乎没有什么不同。我如何解释选择哪一个?(在收集之后的这一点上,这可能是同步的,不重要吗?)这是正确的,在这种情况下,它们都是相同的,因为collect
只向flatMap
发送一个值。该策略告诉flatMap
如何处理多个值。我去年写了一个答案,解释了不同的策略:
context.saveSignal()
.mapError { MyError.saveFailed(error: $0) }
.then(SignalProducer(value: values))