我有以下管道设置,由于某些原因我无法理解,第二个flatMap被跳过:
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)
}
请参阅从upload
方法开始的转换/签名。当我说跳过时,我的意思是即使我添加了断点或日志语句,它们也不会被执行。
知道如何调试或如何修复吗?
谢谢。
编辑:它很可能与第一个flatMap
中的map
有关,但还不确定如何修复它。请参阅此链接。
编辑2:版本
- ReactiveCocoa (10.1.0):
- ReactiveObjC (3.1.1)
- ReactiveObjCBridge (6.0.0):
- ReactiveSwift (6.1.0)
编辑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)
}
}
}
}
发送完成是有意义的,所以我不能改变这一点。有什么方法可以更改flatMap以仍然执行我想要执行的操作吗?
我认为您的第二个flatMap
从未被执行的原因是saveSignal
从未发送值;它只是以CCD_ 8事件或CCD_。这意味着永远不会调用map
,也不会将任何值传递给您的第二个flatMap
。你可以通过这样做来修复它:
context.saveSignal()
.mapError { MyError.saveFailed(error: $0) }
.then(SignalProducer(value: values))
您只需创建一个新的生产者,在saveSignal
成功完成后发送values
,而不是使用map
(因为没有要映射的值,所以它什么都不做(。