0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【物語で学ぶ Swift Concurrency】タスクグループの使い方

Posted at

登場人物:

  • 先生(プログラミング担当の教師)
  • 生徒(ユウタ)(高校1年生、プログラミング初心者)

📌 シーン1: タスクグループって何?

放課後、プログラミングの授業が終わった後、ユウタは先生に質問をした。

ユウタ「先生、Swiftで複数のAPIを同時に呼び出せるって聞いたんですけど、本当ですか?」

先生「本当だよ。TaskGroup を使うと、複数の非同期処理を並列で実行できるんだ。」

ユウタ「並列…ですか? 普通に await で順番に実行するのとは違うんですか?」

先生「そうだね。例えば、SNSアプリで友達のリスト投稿記事のタイトルを取得するとしよう。APIがそれぞれ分かれていて、片方が3秒、もう片方が1秒かかるとする。」

ユウタ「もし順番に実行したら、3秒 + 1秒で4秒かかりますよね?」

先生「その通り。でも TaskGroup を使えば、同時に実行できるから、かかる時間は長い方の3秒だけで済むんだ。」

ユウタ「えぇ!? そんなことができるんですか?」

先生「もちろんだよ。実際にコードを見てみよう。」


📌 シーン2: 実際のコードを見てみよう

先生がホワイトボードにコードを書き始める。

// TaskGroupView.swift
struct MypageInfo {
    let friends: [String]
    let airticleTitles: [String]
}

struct MypageInfo { let friends: [String] let airticleTitles: [String] }

ユウタ「この MypageInfo は何をするんですか?」

先生「これは、マイページの情報をひとつのデータとしてまとめるための struct だよ。友達のリストと、投稿記事のタイトルを保持するんだ。」

ユウタ「なるほど。それじゃあ、実際にAPIを呼び出す部分は?」

先生「ここだよ。」

// 友達のリストを取得(3秒かかる)
private func fetchFriends() async -> [String] {
    await Util.wait(seconds: 3)
    return ["たかし", "ゆうた", "さくら", "けんじ"]
}

// 記事タイトルを取得(1秒かかる)
private func fetchArticles() async -> [String] {
    await Util.wait(seconds: 1)
    return ["ペットを飼い始めました", "うちの猫の名前はミケ", "ミケが勉強の邪魔をしてきます"]
}

ユウタ「え? await Util.wait(seconds: 3) って何ですか?」

先生「これは、ダミーの待機処理 だよ。本当なら fetchFriends()fetchArticles() ではAPIを呼ぶんだけど、ここでは時間のかかる処理を再現するために、指定秒数待機するようにしているんだ。」


📌 シーン3: TaskGroup を使って並列実行

先生「じゃあ TaskGroup を使って fetchFriendsfetchArticles同時に呼び出す方法を教えるね!」

// TaskGroup を使って並列に API を実行
func fetchMyPageData() async -> MypageInfo {
    var friends: [String] = []
    var articles: [String] = []

    await withTaskGroup(of: FetchType.self) { group in
        // 友達リストを取得するタスク
        group.addTask {
            let friendsList = await self.fetchFriends()
            return FetchType.friends(friendsList)
        }

        // 記事タイトルを取得するタスク
        group.addTask {
            let articlesList = await self.fetchArticles()
            return FetchType.articles(articlesList)
        }

        // タスクの結果を取得
        for await fetchResult in group {
            switch fetchResult {
            case .friends(let f):
                friends = f
            case .articles(let a):
                articles = a
            }
        }
    }

    return MypageInfo(friends: friends, airticleTitles: articles)
}

ユウタwithTaskGroup って何ですか?」

先生TaskGroup を作って、その中で addTask を使って複数のタスクを並列に実行する方法だよ。」

ユウタ「つまり fetchFriendsfetchArticles が同時に実行されるんですか?」

先生「そういうこと!このコードだと fetchFriends が3秒、fetchArticles が1秒かかるけど、TaskGroup を使うことで、かかる時間は3秒だけで済むんだ。」

ユウタ「おぉー!普通に await で順番に実行するより、めっちゃ速いじゃないですか!」


📌 シーン4: TaskGroup の動作を図で理解しよう

先生がホワイトボードにタスクの流れを書いた。

親タスク: fetchMyPageData()
 ├── 子タスク: fetchFriends()(3秒)
 ├── 子タスク: fetchArticles()(1秒)

ユウタ「なるほど、親タスクが2つの子タスクを同時に実行して、それぞれの結果を集めて MypageInfo を作るんですね!」

先生「その通り!しかも for await を使えば、結果を1つずつ処理できるから便利なんだよ。」


📌 シーン5: TaskGroup を使うメリット

ユウタ「先生、TaskGroup を使うと、どんなメリットがあるんですか?」

先生「主に3つあるよ!」

  1. 処理時間の短縮

    • 普通に await で順番に実行すると4秒かかるけど、 TaskGroup なら3秒で終わる!
  2. 並列処理の簡単な実装

    • TaskGroup を使えば、非同期処理を簡単に並列実行できる。
  3. エラー処理の強化

    • もし1つのタスクがエラーになっても、他のタスクは影響を受けずに実行を続けられる

🎉 まとめ

  • TaskGroup を使うと APIを並列実行 できる!
  • addTask複数のタスクを同時に開始できる。
  • for await を使うと 結果を簡単に取得 できる。

ユウタ「なるほど!Swiftの TaskGroup ってすごいですね!」

先生「そうだね!非同期処理をスムーズに書けるようになるから、ぜひ使ってみよう!」

ユウタ「はい!今日の授業、めちゃくちゃ勉強になりました!」

先生「それはよかった!次の授業も楽しみにしていてね!」

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?