登場人物:
- 先生(プログラミング担当の教師)
- 生徒(ユウタ)(高校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
を使って fetchFriends
と fetchArticles
を同時に呼び出す方法を教えるね!」
// 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
を使って複数のタスクを並列に実行する方法だよ。」
ユウタ「つまり fetchFriends
と fetchArticles
が同時に実行されるんですか?」
先生「そういうこと!このコードだと fetchFriends
が3秒、fetchArticles
が1秒かかるけど、TaskGroup
を使うことで、かかる時間は3秒だけで済むんだ。」
ユウタ「おぉー!普通に await
で順番に実行するより、めっちゃ速いじゃないですか!」
📌 シーン4: TaskGroup
の動作を図で理解しよう
先生がホワイトボードにタスクの流れを書いた。
親タスク: fetchMyPageData()
├── 子タスク: fetchFriends()(3秒)
├── 子タスク: fetchArticles()(1秒)
ユウタ「なるほど、親タスクが2つの子タスクを同時に実行して、それぞれの結果を集めて MypageInfo
を作るんですね!」
先生「その通り!しかも for await
を使えば、結果を1つずつ処理できるから便利なんだよ。」
📌 シーン5: TaskGroup
を使うメリット
ユウタ「先生、TaskGroup
を使うと、どんなメリットがあるんですか?」
先生「主に3つあるよ!」
-
処理時間の短縮
- 普通に
await
で順番に実行すると4秒かかるけど、TaskGroup
なら3秒で終わる!
- 普通に
-
並列処理の簡単な実装
-
TaskGroup
を使えば、非同期処理を簡単に並列実行できる。
-
-
エラー処理の強化
- もし1つのタスクがエラーになっても、他のタスクは影響を受けずに実行を続けられる。
🎉 まとめ
-
TaskGroup
を使うと APIを並列実行 できる! -
addTask
で複数のタスクを同時に開始できる。 -
for await
を使うと 結果を簡単に取得 できる。
ユウタ「なるほど!Swiftの TaskGroup
ってすごいですね!」
先生「そうだね!非同期処理をスムーズに書けるようになるから、ぜひ使ってみよう!」
ユウタ「はい!今日の授業、めちゃくちゃ勉強になりました!」
先生「それはよかった!次の授業も楽しみにしていてね!」