LoginSignup
0
1

More than 1 year has passed since last update.

JavaScriptから学ぶSwiftで新しく対応したasync、await

Posted at

Swiftでasyncとawait機能が対応した。
自分自身Swift以外の言語の素養がなく、asyncとawaitとはなんぞやというところから勉強したのでその記録
async、awaitの学習教材としてJavaScriptの言語仕様を見ている

前提知識として、JavaScriptでのasync await

Promise型 

非同期処理の戻り値であり、非同期が完了するまで、その実態はundefinedになる。

戻り値が返ってきたら、その戻り値がラップされた型となる。戻り値が返ってきたタイミングで自身のthen()メソッドを呼ぶ

getDate()
.then(function(data) {

    return getYear(data)

}) .then(function(year) {

    return getSomething(year)

}) .then(function(item) {

    getAnotherThing(item)

})

async

非同期の戻り値(Promise)が返ってくる (asyncで呼ばれるメソッドは基本バックグラウンドで実行される)

async function(){
    getDate()
    .then(function(data) {

        return getYear(data)

    }) .then(function(year) {

        return getSomething(year)

    }) .then(function(item) {

        getAnotherThing(item)

    })
}.then(function(data){
  // 戻り値がPromiseなので更なるthenを実行することもできる
})

await

asyncな処理( Promiseが返ってくるような処理)において、Promiseの値が決定するまでその場で待機してくれる

function myPromise(num) {
  return new Promise(function(resolve) {

    setTimeout(function() { resolve(num * num) }, 3000)

  })
}

async function myAsync() {
          // ここで約3秒待機する
    const result = await myPromise(10);
         // ここは実行されない
    console.log(result);

}

myAsync();

awaitの使い所 

then()で繋げなくて良くなる

myPromise(10).then(function(data) {

    console.log(data);
    return myPromise(100)

}).then(function(data) {

    console.log(data);
    return myPromise(1000)

}).then(function(data) {

    console.log(data);

})

// これをawaitを使うと下のようにかける!

async function myAsyncAll() {

    console.log(await myPromise(10));
    console.log(await myPromise(100));
    console.log(await myPromise(1000));

}

myAsyncAll();

Swiftで

だいたい一緒 asyncのなかでUIを触りたいときはMainActor.runでメインスレッドでの実行を明示的にする

enum CustomError:Error {
    case badURL
    case badImage
}

func fetchData(urlString:String) async -> Result<CustomModel,CustomError>{
    let request = URLRequest(url: URL(string: urlString)!)
    guard let (data, response) = try? await URLSession.shared.data(for: request, delegate: nil),(response as? HTTPURLResponse)?.statusCode == 200 else {
        return .failure(.badURL)
    }
    let model = convertDataToModel(data: data)
    return .success(model)
}

struct CustomModel{

}

func convertDataToModel(data:Data)->CustomModel{
    return .init()
}

// 一回のみの実行 (fetchDataの処理が完了したら、switch文の中身を実行)
func executeFetchData() async{
    switch await fetchData(urlString: "http://example.com"){
    case .success(let model):
        print(model)

        await MainActor.run{ [weak self] in
            self?.label = model.text
        }
    case .failure(let error):
        print(error)
    }
}

// 複数回の実行
func executeMultipleFetchData() async {
    switch await fetchData(urlString: "http://example.com"){
    case .success(let model):
        print(model)
        await MainActor.run{ [weak self] in
            tableViewSectionTitle[0] = model.text
        }
        switch await fetchData(urlString: "http://example2.com"){
        case .success(let model2):
            await MainActor.run{ [weak self] in
                tableViewSectionTitle[1] = model2.text
            }
        case .failure(let error):
            print(error)
        }
    case .failure(let error):
        print(error)
    }
}
0
1
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
1