如何在 swift 中包含多个功能的完成处理程序?
Posted
技术标签:
【中文标题】如何在 swift 中包含多个功能的完成处理程序?【英文标题】:How to include completion handlers for multiple functions in swift? 【发布时间】:2018-03-07 11:27:09 【问题描述】:考虑这段代码:
func test()
A()
B()
C()
D()
E()
这里的每个函数都有自己的一组操作,例如调用 API、解析它们、将结果写入文件、上传到服务器等。
我想一个一个地运行这个函数。我阅读了有关完成处理程序的信息。我对完成处理程序的问题是:
为理解完成处理程序而给出的所有示例都只有两种方法 我不想将此函数放在其他函数中。我只想要Test()
函数中的所有函数调用(A 到 E)
有人可以帮忙吗?
【问题讨论】:
我想一个一个地运行这个函数。 你认为为什么不是这样?注意:完成处理程序是在某事结束时执行的“代码”(通常是一些异步操作) 【参考方案1】:这很容易做到,你只需要添加一个闭包参数来完成调用。例如:
func a(completion: (() -> Void))
// When all async operations are complete:
completion()
func b(completion: (() -> Void))
// When all async operations are complete:
completion()
func c(completion: (() -> Void))
// When all async operations are complete:
completion()
func d(completion: (() -> Void))
// When all async operations are complete:
completion()
func e(completion: (() -> Void))
// When all async operations are complete:
completion()
func test()
a
b
c
d
e
// All have now completed.
如您所见,这看起来很可怕。多个异步操作(非并发)的一个问题是您最终会遇到这种可怕的嵌套。
解决方案确实存在,我个人推荐PromiseKit。它将块封装在简单的链接方法中,这要干净得多。
【讨论】:
我认为,我们应该在每个方法的(A-E)末尾添加这一行:completion()【参考方案2】:看看反应式编程和可观察链。 RxSwift 将是您的绝佳图书馆。反应式编程现在非常流行,并且正是为了解决像您这样的问题而创建的。它使您能够轻松创建将输入转换为所需输出的流程(如装配线)。例如,您在 Rx 中的代码如下所示:
A()
.flatMap resultsFromA in
B(resultsFromA)
.flatMap resultsFromB in
C(resultsFromB)
.flatMap resultsFromC in
D(resultsFromC)
.flatMap resultsFromD in
E(resultsFromD)
.subscribe(onNext: finalResult in
//result from the process E, subscribe starts the whole 'assembly line'
//without subscribing nothing will happen, so you can easily create observable chains and reuse them throughout your app
)
此代码示例将创建一个流程,您可以将初始 API 调用 (A) 的结果转换为解析结果 (B),然后将解析结果写入文件 (C) 等。这些流程可以是同步的,也可以是同步的异步。反应式编程可以理解为 类固醇上的 Observable 模式。
【讨论】:
Rx 是一个不错的方法,但它是一个陡峭的学习曲线,需要整个范式转变。如果你有能力做到这一点,那么它绝对是一个好主意。不幸的是,我不是,因此发现 PromiseKit 是一个不错的折衷方案。 我同意 Jacob King 的观点,这需要范式转变和一些时间来调整。但是,回报非常好,最终您会学到一件有价值的东西,可以长期提高您的工作效率。 正如 FruitAdict 所说,如果您能够做出转变,您将获得长期回报。以上是关于如何在 swift 中包含多个功能的完成处理程序?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Express 的多个文件中包含路由处理程序? [复制]
在 tapGesture 动作选择器中包含协议功能 - iOS Swift
如何在 Xcode 中的 UI 测试类的目标中包含 SwiftyUserDefaults.swift?