如何在swift中包含多个函数的完成处理程序?

时间:2018-03-07 11:27:10

标签: swift function synchronization completionhandler

考虑以下代码:

func test() {
    A()
    B()
    C()
    D()
    E()
}

这里的每个函数都有自己的一组动作,比如调用API,解析它们,将结果写入文件,上传到服务器等等。

我想逐个运行这个函数。我读到了完成处理程序。完成处理程序的问题是:

  • 所有用于理解完成处理程序的示例只有两种方法
  • 我不想将此功能放在其他功能中。我希望单独Test()功能
  • 内的所有函数调用(A到E)

有人可以为此提供帮助吗?

2 个答案:

答案 0 :(得分:2)

这很容易做到,你只需要在完成时调用一个闭包参数。例如:

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。它将块封装在简单的链接方法中,这种方法更加清晰。

答案 1 :(得分:0)

看一下反应式编程和可观察链。 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)等。这些进程可以是同步的或异步。反应性编程可以理解为类固醇的可观察模式。