👽

【Swift】async/awaitを解説 クロージャいらない?

2024/03/31に公開

async/awaitの解説

async/awaitで非同期処理を簡単に書けるようになりました。
非同期処理とは、複数のプログラムを同時に実行できる仕組みです。
これまでは、クロージャを使用して非同期処理を行っていましたが、async/awaitが導入されました。

async/awaitのメリット

学習コストが低い。
ネストせずに複雑な処理を書くことができる。
簡潔に書けるので複数人でコードを書いていても非同期処理を見落とさない。

比較

年齢を入力すると2倍にして返してくれる非同期処理を書くとすると
クロージャ

class Person {
    var name: String = "ore"
    var age: Int = 23
    
    func increaseAge(completion: @escaping (Int) -> Void) {
        completion(age)
    }
 }
 
 func printAge() -> Int{
        var myAge = 0
        let me = Person()
        me.increaseAge(completion: { result in
            myAge = result * 2
        })
        return myAge
}

async/awaitを使う

class Person {
    var name: String = "ore"
    var age: Int = 23
    
    func awaitIncreaseAge(number: Int) async -> Int {
        return number * 2
    } 
}
func printAge() async -> Int{
        var myAge = 0
        let me = Person()
        myAge = await me.awaitIncreaseAge(number: me.age)
        return myAge
 }

変数や関数の名前がいけてないのは今回は勘弁してください!!

解説

この程度のコードでは違いが分かりにくいですが、非同期処理が二つ重なった場合にクロージャだとネストが深くなってしまいます。
また、クロージャの場合は括弧が多すぎて直感的にコードを解読しにくいと思います。
しかし、async/awaitを使う方法では、関数にasyncとかき呼び出す際にawaitをつけるだけで非同期処理が行われます。

番外編

同期的に行わなかればいけないとき
UIの変更など非同期の処理(上記の例だとawaitIncreaseAgeが非同期の処理)を行わなければいけないときはTaskで囲む。

func printAge() -> Int{
        var myAge = 0
        let me = Person()
        Task{
        myAge = try await me.awaitIncreaseAge(number: me.age)
        }
        return myAge
 }

上記のようにすることで、非同期を同期的に行える。

Discussion