Xcode 13 中即将推出的 Swift 5.5(此时仍处于测试阶段)使用非常相似的 async-await 模式。见The Swift Programming Language: Concurrency。
在此期间,不幸的是,有许多令人眼花缭乱的替代方案。例如,有各种各样的第三方 Promise/Future 框架。或者是声明性的Combine 框架,它是在几年前随着SwiftUI 的非命令模式的出现而推出的。
所有这些都说了,您将在 Swift 代码中看到的最常见模式是使用转义“closures”,它们实际上是作为参数传递给函数的代码单元,并且函数在异步任务完成时调用。在该模式中,您不需要await,而只是指定异步任务完成时要执行的操作。例如,在这个函数中,它有一个名为completion 的参数,这是一个在异步任务完成时调用的闭包:
func fetch(using value: Int, completion: @escaping (Result<Foo, Error>) -> Void) {
let url = …
let task = URLSession.shared.dataTask(with: url) { data, response, error in
// handle errors, if any, e.g.:
if let error == error else {
completion(.failure(error))
return
}
// parse data into `Foo` here, and when done, call the `completion closure:
…
completion(.success(foo))
}
task.resume()
}
然后你会这样称呼它:
fetch(using: 42, completion: { result in
// this is called when the fetch finishes
switch result {
case .failure(let error): // do something with `error`
case .success(let foo): // do something with `foo`
}
})
// note, execution will continue here, and the above closure will
// be called later, so do not try to use `foo` here
或者,使用更简洁的“尾随闭包”语法:
fetch(using: 42) { result in
// this is called when the fetch finishes
switch result {
case .failure(let error): // do something with `error`
case .success(let foo): // do something with `foo`
}
}
// note, execution will continue here, and the above closure will
// be called later, so do not try to use `foo` here
如果您想在一系列通话结束时收到通知,您可以使用DispatchGroup,例如
let group = DispatchGroup()
for value in values {
group.enter()
fetch(using: value) { result in
// do something with result
group.leave()
}
}
group.notify(queue: .main) {
// this is called when every `enter` call is matched up with a `leave` Call
}
您是否坚持使用非常熟悉的async-await 模式的 Swift 5.5 测试版,使用第三方的 future/promise 库,使用 Combine,还是使用传统的闭包 -基于模式,如上所示。
至少,我建议您熟悉后一种模式,因为它是目前 Swift 中的主要技术。但请放心,熟悉的 async-await 模式即将推出,因此如果您愿意等待它完成测试过程(或加入该测试过程),请检查一下。