Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
未执行ReactiveSwift管道平面映射体转换_Swift_Flatmap_Reactive Swift - Fatal编程技术网

未执行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))