在5.5之前進(jìn)行異步操作,調(diào)用返回時(shí),使用
completion handler
參數(shù)進(jìn)行處理。現(xiàn)在提供了async/awiat 進(jìn)行異步并發(fā)處理斟湃。
基本使用方式:
func sendCode() async throws -> Data{
let request = URLRequest.init(url: URL(string: "")!)
let (data, response) = try await URLSession.shared.data(for: request)
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
throw RequestError.notdata
}
return data
}
方法后面跟上async
表示是一個(gè)異步函數(shù)。如果調(diào)用異步函數(shù)
func groupTaskLoadData() async throws {
do{
try await sendCode()
}catch let error as RequestError{
if error == RequestError.urlerror {
print("xxxx")
}
}
}
在正常返回的函數(shù)中使用 async 修飾的func時(shí)檐薯,需要用Task{} 進(jìn)行包裝凝赛,否則報(bào)錯(cuò)
Cannot pass function of type '() async -> Void' to parameter expecting synchronous function type
使用方式:
Button("Test Async") {
Task{
await sendCode()
}
}
屬性也可以 async properties
var isAuth: Bool {
get async {
await self.sendCode()
}
}
使用異步屬性,必須只能是get
屬性坛缕∧沽裕可寫(xiě)屬性不能使用異步屬性。
Continuation 模式
如果之前使用的
completion handler
方式的方法赚楚,或者第三方的庫(kù)中使用的completion 方式毙沾。需要進(jìn)行包裝后使用。swift 提供了withUnsafeContinuation
宠页、withCheckedThrowingContinuation
左胞、withCheckedContinuation
函數(shù)。
public func resume(returning x: T) 接收 completion
中的數(shù)據(jù)返回举户,轉(zhuǎn)換成async
函數(shù)返回烤宙。
public func resume(throwing x: E) 進(jìn)行拋出異常
withCheckedContinuation
方法中的checked
會(huì)在運(yùn)行時(shí)對(duì)操作進(jìn)行檢查:是否調(diào)用resume
進(jìn)行返回。如果不調(diào)用會(huì)造成資源泄露俭嘁。多次調(diào)用也會(huì)造成問(wèn)題躺枕。
continuation 有且只能 resume 一次。
withUnsafeContinuation
的工作機(jī)制和withCheckedContinuation
一致,唯一區(qū)別在于運(yùn)行時(shí)不會(huì)對(duì)操作進(jìn)行檢查拐云。但性能更好罢猪。實(shí)際使用中withCheckedContinuation
測(cè)試沒(méi)有問(wèn)題后,正式發(fā)布時(shí)使用withUnsafeContinuation
使用方式如下:
withCheckedContinuation
func sendCodeContinuation() async -> Data{
await withCheckedContinuation{ continuation in
NET.GET(url: "").success { data in
continuation.resume(returning: data)
}
} as! Data
}
如果有拋出異常
withCheckedThrowingContinuation
func sendCodeThrowsContinuation() async throws -> Data{
try await withCheckedThrowingContinuation { (continuation:CheckedContinuation<Data,Error>) in
NET.POST(url: "").success { data in
continuation.resume(returning: data as! Data)
}.failed { error in
continuation.resume(throwing: error as! Error)
}
}