如何在 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?

Xcode 自动完成功能在 Swift 游乐场的 Sources 文件夹中不起作用

如何在我的 Swift 项目中包含一个库?

在 Swift 项目中包含 SQLCipher pod 时如何避免构建错误?