我们将一个整数数组(arr)传递到 cal 函数中,然后返回另一个数组,其中每个元素将传递到 multip 函数中。 乘法函数模拟需要很长时间才能得到结果。
由于我们可以对arr中的每个元素并行调用乘法函数,因此我们不必等待结果。 有没有更好的方法重写cal函数?
func multiply(_ a:Int) async throws -> Int {
try await Task.sleep(nanoseconds: 1000_000_000)
return a*2
}
func cal(_ arr:[Int]) async throws -> [Int] {
try await withThrowingTaskGroup(of: (Int, Int).self) { taskGroup in
for i in 0..<arr.count {
taskGroup.addTask{
let val = try await multiply(arr[i])
return (i, val)
}
}
var res = Array(repeating:0, count: arr.count)
for try await (i,val) in taskGroup {
res[i] = val
}
return res
}
}
var arr = [1,2,3,4]
var res = try await cal(arr)
print(res)
我在操场上尝试过我的方法。效果很好。但我对我的做法不是很熟悉。任何事情都会有帮助的。谢谢。
结果:
[2, 4, 6, 8]
虽然无法保证以真正的并行性调用异步函数,但由于线程/池以及其他内存/资源的可用性,因此在这里排除问题的主观性,您正在做什么没问题,只要您确实想等待
cal(:)
函数完成即可。
如果您不关心
cal(:)
函数被标记为 async
或者出于某种原因想要避免使用 TaskGroup
那么您可以使用两个不同的任务块来实现这一点(非常非常基本的示例):
func foo() {
print("Running")
Task {
await someAsyncFunction()
print("Awaited One")
}
Task {
await someAsyncFunctionTwo()
print("Awaited Two")
}
print("Finished")
}
由此,您可以期望控制台输出类似以下内容的内容(请注意,最后两行可以交换,具体取决于哪一行先完成):
Running
Finished
Awaited One
Awaited Two