Swift 中async/await 简单使用
在 Swift 5.5 中,终于加入了语言级别的异步处理 async/await,这应该会让用回调闭包写异步调用方法时代彻底结束了!
这篇文章就简单总结一下这个功能使用吧。
异步函数
所谓异步,是相对于同步而言,这是一种执行任务的方式,同步的执行任务,任务需要一个一个的顺序执行,前边的好了,后边的才能运行。而异步就不是这样,它不需要等待当前任务执行完成,其他任务就可以执行。
在 Swift 5.5 中,添加了 async
关键字,标记这个函数是一个异步函数。
func getSomeInfo() async -> String { ... }
/// 可以抛出错误的异步函数
func getSomeInfoWithError() async throws -> String { ... }
这里需要注意的是,如果我们想调用异步函数,就必须在其他异步函数或者闭包里面使用 await
关键字。
func runAsyncFunc() async {
let info = await getSomeInfo()
...
}
func runAsyncErrorFunc() async throws {
let info = try await getSomeInfoWithError()
...
}
实际使用异步函数的时候,我们是无法在同步函数里使用的,这时Swift会报错。要使用的话,就需要我们要提供了一个异步执行的环境 Task
。
func someFunc() {
Task {
runAsyncFunc()
}
}
异步序列
如果一个序列中的每个信息都是通过异步获取的,那么就可以使用异步序列的方式遍历获取。前提是序列是遵守AsyncSequence
协议,只要在for in
中添加 await
关键字。
let asyncItems = [asyncItem1, asyncItem2, asyncItem3]
for await item in asyncItems { ... }
多个异步同时运行
这个可以使用叫做异步绑定的方式,就是在每个存储异步返回信息的变量前
边添加async
。
async let a = getSomeInfo()
async let b = getSomeInfo()
async let c = getSomeInfo()
let d = await [a, b, c]
...
这时运行的情况就是 a b c 是同时执行的,也就是所说的并行执行异步任务,即并发。
结构化并发
上边在提到在同步函数中使用异步函数,我们需要添加一个Task
,来提供异步运行的环境。 每个 Task 都是一个单独任务,里面执行一些操作,这操作可以是同步也可以是异步。多个任务执行时,可以把它们添加到一个任务组TaskGroup
中,那么这些任务就有了相同的父级任务,而这些任务Task
又可以添加子任务,这样下来,任务之间就有了明确的层级关系,这也就是所谓的结构化并发
。
任务和任务组
任务组可以更为细节的处理结构化并发,使用方式如下,就在任务组中添加单个任务即可。
func someTasksFunc() {
Task {
await withTaskGroup(of: String.self) { group in
group.addTask {
let a = await getSomeInfo()
...
}
group.addTask {
let b = await getSomeInfo()
...
}
}
}
}
从运行的方式来说,这种使用任务组的情况和异步绑定的效果一样,简单的异步任务,完全可以使用异步绑定的方式。而任务和任务组是为更为复杂的并发情况提供支持,比如任务的优先级,执行和取消等。
如果异步函数是可抛出错误的,使用withThrowingTaskGroup
就行。
解决数据竞争的Actor
在并发过程中,对于同一属性数据的读取或者写入,有时会有奇怪的结果,这些由于在不同的线程,同时进行了操作。消除这种问题的方式,就是使用 Swift 提供的 Actor
类型。 一个和类差不多的类型,但是对自身可变内容进行了隔离。
actor SomeInfo {
var info: String
}
外部在访问其info
属性时,actor 做了隔离,每次只能一个线程访问,直接访问就会报错。而且外部不能进行修改,只有内部才能修改。
外部访问方式就是需要异步执行,在异步环境中,添await
。
let content = SomeInfo(info: "abc")
let info = await content.info)
...
总结
以上就是Swift 5.5 async/await
的简单使用了。了解了这些,就可以日常开发中替代闭包回调,告别回调地狱和处理不完的 completionHandler了。😎
目前官方已经在已有闭包回调处理异步的地方,都增加async异步版本,自行查看文档了解吧。。
另外附上一些很有帮助的文章地址,这些地方都有更为详尽的说明,参考学习起来!
Swift 5.5 有哪些新功能?
http://www.hackingwithswift.com/articles/23…
Swift 并发初步
并发
链接:https://juejin.cn/post/7250375035634090043
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。