1.定義一個(gè)異步的方法
使用async關(guān)鍵字,表示這是一個(gè)異步的方法。這里用withCheckedContinuation配合DispatchQueue.main.asyncAfter模擬一個(gè)網(wǎng)絡(luò)請(qǐng)求。
func testMethod(value: Int) async -> Int {
return await withCheckedContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
let result = value * 2
CWLog(result)
continuation.resume(returning: result)
})
}
}
2.在異步方法中調(diào)用異步方法
使用await關(guān)鍵字
func asyncTestMethod() async {
CWLog("111")
let result = await testMethod(value: 2)
CWLog("222")
}
// 1: 111
// 2: 4
// 3: 222
3.在同步方法中調(diào)用異步方法
使用Task
override func viewDidLoad() {
super.viewDidLoad()
Task {
await testMethod()
}
}
4.并發(fā)執(zhí)行多個(gè)異步方法,并最后統(tǒng)一處理結(jié)果
類似GCD中的dispatch_group, 采用TaskGroup來(lái)實(shí)現(xiàn)
override func viewDidLoad() {
super.viewDidLoad()
CWLog("111")
Task(priority: .background) {
CWLog("222")
let result = await withTaskGroup(of: Int.self, returning: [Int].self) { [weak self] group in
guard let `self` = self else {return []}
// 模擬4個(gè)任務(wù)
for i in 1...4 {
group.addTask {
// 這里處理添加單個(gè)的task
return await self.testMethod(value: i)
}
}
var arr: [Int] = []
// 這里統(tǒng)一處理結(jié)果
for await result in group {
arr.append(result)
}
// 返回結(jié)果
return arr
}
CWLog(result)
}
CWLog("333")
}
在調(diào)用withTaskGroup時(shí):
第一個(gè)參數(shù):每個(gè)異步任務(wù)返回的數(shù)據(jù)類型。
第二個(gè)參數(shù):所有異步任務(wù)執(zhí)行完成后,匯總之后的數(shù)據(jù)類型。
第三個(gè)參數(shù): 閉包,具體業(yè)務(wù)邏輯。
注意:匯總處理的(for await...in...)和addTask時(shí)的(for...in...)順序是不一定對(duì)的上的,最終返回的結(jié)果是無(wú)序的。
如果想要返回的結(jié)果是有序的,可是采用多個(gè)Task的方式來(lái)實(shí)現(xiàn):
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Task { [weak self] in
guard let `self` = self else {return}
let tasks = [1 ,2 ,3 ,4].map { item in
return Task {
return await self.testMethod(value: item)
}
}
let result = await withTaskCancellationHandler {
var values: [Int] = []
for task in tasks {
values.append(await task.value)
}
return values
} onCancel: {
tasks.forEach { $0.cancel() }
}
CWLog(result)
}
}
func testMethod(value: Int) async -> Int {
return await withCheckedContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
let result = value * 2
CWLog(result)
continuation.resume(returning: result)
})
}
}
}
部分場(chǎng)景也可以使用async + let來(lái)實(shí)現(xiàn)。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Task {
CWLog("begin")
async let name = getName()
async let age = getAge()
async let hobby = getHobby()
CWLog(await age)
CWLog(await hobby)
CWLog(await name)
}
}
func getName() async -> String {
return await withUnsafeContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
CWLog("getName")
continuation.resume(returning: "chen wang")
})
}
}
func getAge() async -> Int {
return await withUnsafeContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
CWLog("getAge")
continuation.resume(returning: 18)
})
}
}
func getHobby() async -> [String] {
return await withUnsafeContinuation { continuation in
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
CWLog("getHobby")
continuation.resume(returning: ["game", "book"])
})
}
}
}
上面代碼中,getName、getAge、getHobby這個(gè)三方法也是并行的,不分先后順序。
async let name = getName()
async let age = getAge()
async let hobby = getHobby()