【问题标题】:How to include completion handlers for multiple functions in swift?如何在 swift 中包含多个功能的完成处理程序?
【发布时间】:2018-03-07 11:27:09
【问题描述】:

考虑这段代码:

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

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

我想一个一个地运行这个函数。我阅读了有关完成处理程序的信息。我对完成处理程序的问题是:

  • 为理解完成处理程序而给出的所有示例都只有两种方法
  • 我不想将此函数放在其他函数中。我只想要 Test() 函数中的所有函数调用(A 到 E)

有人可以帮忙吗?

【问题讨论】:

  • 我想一个一个地运行这个函数。 你认为为什么不是这样?注意:完成处理程序是在某事结束时执行的“代码”(通常是一些异步操作)

标签: swift function synchronization completionhandler


【解决方案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 所说,如果您能够做出转变,您将获得长期回报。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多