ReactiveSwift 管道 flatMap 主体转换未执行
ReactiveSwift pipeline flatMap body transform not executed
我有以下管道设置,由于某些我无法理解的原因,跳过了第二个 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: [=10=]) } // SignalProducer<[Signal<(), MyError>.Event], MyError>
})
.flatMap(.merge, { values -> SignalProducer<(), MyError> in
if let error = values.first(where: { [=10=].error != nil })?.error {
return SignalProducer(error: error)
} else {
return SignalProducer(value: ())
}
})
.on(failed: logError)
}
参见 transformations/signatures 从 upload
方法开始。
当我说跳过时,我的意思是即使我添加断点或日志语句,它们也不会被执行。
知道如何调试或修复吗?
谢谢。
编辑:它很可能与第一个 flatMap
中的 map
有关,但还不确定如何修复它。
看到这个 link.
编辑 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
从不发送值;它只是以 completed
事件或 error
事件结束。这意味着永远不会调用 map
,并且永远不会将任何值传递给您的第二个 flatMap
。您可以通过执行以下操作来修复它:
context.saveSignal()
.mapError { MyError.saveFailed(error: [=10=]) }
.then(SignalProducer(value: values))
而不是使用 map
(它什么也不做,因为没有要映射的值),您只需创建一个新的生产者,它在 saveSignal
成功完成后发送 values
。
我有以下管道设置,由于某些我无法理解的原因,跳过了第二个 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: [=10=]) } // SignalProducer<[Signal<(), MyError>.Event], MyError>
})
.flatMap(.merge, { values -> SignalProducer<(), MyError> in
if let error = values.first(where: { [=10=].error != nil })?.error {
return SignalProducer(error: error)
} else {
return SignalProducer(value: ())
}
})
.on(failed: logError)
}
参见 transformations/signatures 从 upload
方法开始。
当我说跳过时,我的意思是即使我添加断点或日志语句,它们也不会被执行。
知道如何调试或修复吗?
谢谢。
编辑:它很可能与第一个 flatMap
中的 map
有关,但还不确定如何修复它。
看到这个 link.
编辑 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
从不发送值;它只是以 completed
事件或 error
事件结束。这意味着永远不会调用 map
,并且永远不会将任何值传递给您的第二个 flatMap
。您可以通过执行以下操作来修复它:
context.saveSignal()
.mapError { MyError.saveFailed(error: [=10=]) }
.then(SignalProducer(value: values))
而不是使用 map
(它什么也不做,因为没有要映射的值),您只需创建一个新的生产者,它在 saveSignal
成功完成后发送 values
。