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