💭

【Swift】async-await / async-let / Task Groupのイメージ

2024/10/21に公開

はじめに

Swift Concurrencyについて学ぶ機会があったので、イメージをコード付きで言語化しておきます。

環境

  • Xcode 16.0
  • Swift 6.0

async-await

コード
func first() async -> Int {
    try! await Task.sleep(for: .seconds(3))
    print("finished No.1")
    return 1
}

func second() async -> Int {
    try! await Task.sleep(for: .seconds(2))
    print("finished No.2")
    return 2
}

func third() async -> Int {
    try! await Task.sleep(for: .seconds(1))
    print("finished No.3")
    return 3
}

let result_First = await first()
let result_Second = await second()
let result_Third = await third()

let results = (result_First, result_Second, result_Third)

print(results)

async-let

コード
func first() async -> Int {
    try! await Task.sleep(for: .seconds(3))
    print("finished No.1")
    return 1
}

func second() async -> Int {
    try! await Task.sleep(for: .seconds(2))
    print("finished No.2")
    return 2
}

func third() async -> Int {
    try! await Task.sleep(for: .seconds(1))
    print("finished No.3")
    return 3
}

async let result_First = first()
async let result_Second = second()
async let result_Third = third()

let results = await (result_First, result_Second, result_Third)

print(results)

Task Group

Task Groupは動的に子タスクを生成する際に役立つ。
async letの個数が動的になる場合に有効。

ユースケース

  • APIから取得した複数のidをもとに、非同期処理を並行して行う
コード
func takeTime(_ time: Int) async -> Int {
    try! await Task.sleep(for: .seconds(time))
    print("finished: \(time) sec.")
    return time
}

var results: [Int] = [] {
    didSet {
        print(results)
    }
}

await withTaskGroup(of: (Int).self) { group in
    for i in 1...5 {
        group.addTask {
            return await takeTime(i)
        }
    }
    
    for await result in group {
        results.append(result)
    }
}

Discussion