class Numbers {
let info = Info()
func getNum() async -> Int {
let time = UInt64.random(in: 2...4)
print("延时:\(time): ", Thread.current)
return await random(time)
}
func getThrowNum() async throws -> Int {
let time = UInt64.random(in: 2...4)
print("延时:\(time): ", Thread.current)
if time == 4 {
throw NSError(domain: "4秒", code: 100)
}
return await random(time)
}
func random(_ time: UInt64) async -> Int {
try? await Task.sleep(nanoseconds: time * 1_000_000_000)
return Int.random(in: 0...100)
}
}
异步串行
func serial() async {
let numbers = Numbers()
var beginDate = Date()
print(Thread.current)
let num1 = await numbers.getNum()
print(num1, " ", beginDate.distance(to: Date()))
beginDate = Date()
let num2 = await numbers.getNum()
print(num2, " ", Date().timeIntervalSince(beginDate))
}
<_NSMainThread: 0x600000e48700>{number = 1, name = main}
延时:2: <_NSMainThread: 0x600000e48700>{number = 1, name = main}
20 2.001320004463196
延时:4: <_NSMainThread: 0x600000e48700>{number = 1, name = main}
88 4.379878997802734
异步并发
func concurrent() async {
let numbers = Numbers()
async let num1 = numbers.getNum()
async let num2 = numbers.getNum()
print(Thread.current)
let beginDate = Date()
let nums = await [num1, num2]
print(Date().timeIntervalSince(beginDate))
print(nums)
}
<_NSMainThread: 0x6000002907c0>{number = 1, name = main}
延时:4: <NSThread: 0x6000002c0c80>{number = 6, name = (null)}
延时:3: <NSThread: 0x6000002c0c80>{number = 6, name = (null)}
4.377479910850525
[90, 32]
TaskGroup
func group() async {
let begin = Date()
let results = await withTaskGroup(of: Int.self) { taskGroup -> [Int] in
for _ in 0..<4 {
taskGroup.addTask {
let nums = Numbers()
return await nums.getNum()
}
}
var results = [Int]()
for await result in taskGroup {
results.append(result)
}
return results
}
print(begin.distance(to: Date()))
print(results)
}
延时:4: <NSThread: 0x600002047540>{number = 7, name = (null)}
延时:3: <NSThread: 0x600002047540>{number = 7, name = (null)}
延时:3: <NSThread: 0x600002047540>{number = 7, name = (null)}
延时:4: <NSThread: 0x600002047540>{number = 7, name = (null)}
4.001741886138916
[55, 89, 60, 46]
func throwGroup() async throws {
let begin = Date()
let results = try await withThrowingTaskGroup(of: Int.self, body: {
taskGroup -> [Int] in
for _ in 0..<4 {
taskGroup.addTask {
let nums = Numbers()
return try await nums.getThrowNum()
}
}
var results = [Int]()
for try await result in taskGroup {
results.append(result)
}
return results
})
print(begin.distance(to: Date()))
print(results)
}
延时:4: <NSThread: 0x600003ce2a80>{number = 7, name = (null)}
延时:4: <NSThread: 0x600003ce2a80>{number = 7, name = (null)}
延时:3: <NSThread: 0x600003ce2a80>{number = 7, name = (null)}
延时:2: <NSThread: 0x600003ce2a80>{number = 7, name = (null)}
Error Domain=4秒 Code=100 "(null)"
Actor
actor Info {
var age: Int = 0
func setAge(_ age: Int) {
self.age = age
}
}
func setInfo() async {
let num = await getNum()
await info.setAge(await getNum())
await print(info.age)
}
actor无法直接使用set方法,Error:Actor-isolated property 'age' can not be mutated from a non-isolated context
@MainActor
var age: Int = 0
func setInfo() async {
let num = await getNum()
await MainActor.run {
age = num
}
await print(age)
}
Result
extension Result where Failure == Error {
init(operation: @escaping @Sendable () async throws -> Success) async {
do {
let success = try await operation()
self.init(catching: { success })
} catch let err {
self.init(catching: { throw err })
}
}
}
Result
和async
的结合:
@Sendable
func throwGroup() async throws {
let begin = Date()
let results = try await withThrowingTaskGroup(of: Int.self, body: { taskGroup -> [Int] in
for _ in 0..<4 {
taskGroup.addTask {
let nums = Numbers()
return try await nums.getThrowNum()
}
}
var results = [Int]()
for try await result in taskGroup {
results.append(result)
}
return results
})
print(begin.distance(to: Date()))
print(results)
}
let result = await Result(operation: throwGroup)
print(result)
延时:2: <NSThread: 0x600001a99480>{number = 5, name = (null)}
延时:2: <NSThread: 0x600001a99480>{number = 5, name = (null)}
延时:3: <NSThread: 0x600001a99480>{number = 5, name = (null)}
延时:2: <NSThread: 0x600001a99480>{number = 5, name = (null)}
3.001500964164734
[26, 34, 67, 62]
success()
网友评论