我有一系列异步方法定义如下:
func step1(input: Step1InputData, completion: (Step1OutputData -> Void)) { /* do something */ }
func step2(input: Step1OutputData, completion: (Step2OutputData -> Void)) { /* do something */ }
// etc...
如您所见,step1
的输出是step2
的输入。这些类型都实现了 StepData
协议(protocol):
protocol StepData {}
class Step1InputData : StepData { }
class Step1OutputData : StepData { }
class Step2OutputData : StepData { }
最后,我有了这个自定义运算符:
infix operator => { associativity left }
func => <P:StepData, Q:StepData, R:StepData> (left:((P, Q -> Void) -> Void), right:((Q, R -> Void) -> Void)) -> ((P, R -> Void) -> Void) {
return { (x, completion) in
left(x, { y in
right(y, completion)
})
}
}
...这意味着我可以编写以下内容:
let combinedStep = step1 => step2
这很棒,因为它具有超强的可读性,而且至关重要它在步骤之间强制执行类型安全。
问题是我希望能够保留 combinedStep
的进度。例如,step1
可以是图片上传,step2
可以是本地存储写入。如果 step2
失败,下次尝试时,我想从中断的地方继续,而不是重新上传图像。当然,可以将任意数量的步骤链接在一起。
我可以想出一个系统,该系统具有一系列步骤并管理步骤之间的数据传递,并且能够保持进度,但是,我想不出办法在保持编译时类型安全的同时做到这一点。
有更多函数式编程经验的人能为我指明正确的方向吗?
最佳答案
我建议您研究像 PromiseKit 这样的框架, BrightFutures , 和 ReactiveCocoa .
那些框架与你处于相同的问题和解决方案空间,需要组合的异步操作,它们都提供了多种处理错误和重试的方法。
如果您喜欢其中的任何一个,您可以采用它们来代替您的自定义实现,并利用大型开发人员社区的支持。或者,您可以从他们的代码中找到灵感,带回您的代码中。
享受
关于ios - 如何复合函数并持久化进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34227147/