本記事について
Swift Concurrencyを用いた並列処理において、曖昧な理解で実装していたのでメモとして残します。
async let
を用いて並列処理を行う際、実装方法によってタスク結果の取得タイミングを変えることが可能です。
具体例
以下、2パターンの挙動の実現が可能になります。
- パターン1:両方のタスクが完了するまで待機してから、両方の結果を同時に取得
- パターン2:各タスクの結果が利用可能になるとすぐにそれを取得し、次の結果の取得を待つ
もう少しイメージしやすいように、イメージ図とコードを示します。
パターン1
Pattern1.swift
async let response1 = fetch1()
async let response2 = fetch2()
let results = await (response1, response2)
パターン2
Pattern2.swift
async let response1 = fetch1()
async let response2 = fetch2()
let result1 = await response1
let result2 = await response2
実装内容
Playgroundでコピペで動きます。
※ エラーハンドリングは無視しています。
ParallelProcessingSample.swift
func fetch1() async -> String {
// 1秒のdelay
try? await Task.sleep(nanoseconds: 1 * 1_000_000_000)
return "Result from fetch1"
}
func fetch2() async -> String {
// 2秒のdelay
try? await Task.sleep(nanoseconds: 2 * 1_000_000_000)
return "Result from fetch2"
}
// パターン1のテスト
func testPattern1() async {
async let response1 = fetch1()
async let response2 = fetch2()
// response1, 2両方の結果が利用可能になるまで待機
let results = await (response1, response2)
print(results)
}
// パターン2のテスト
func testPattern2() async {
async let response1 = fetch1()
async let response2 = fetch2()
let result1 = await response1
let result2 = await response2
// response1の結果が利用可能になるまで待機し、
// その後、response2の結果が利用可能になるまで待機
// resuponse1の結果が先に利用可能になればresult1の代入が行われ、response2の結果を待つ
print(result1, result2)
}
// 非同期関数を実行
Task {
await testPattern1()
await testPattern2()
}
以上です。