15
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

【Swift】Combine.frameworkのFutureとDeferredと即時実行、遅延実行

以前投稿した内容で
Combine.frameworkのFutureはインスタンスを生成した時点で
中のクロージャを実行させるということについて書きました。

https://qiita.com/shiz/items/f089c93bdebfaef2196f
https://developer.apple.com/documentation/combine/future

この場合
Subscribeをしていないのに処理が実行されてしまい
無駄にリソースを消費してしまう可能性や
副作用を起こして思わぬ動作をしてしまう可能性もあります。

そういう場合Deferredを活用する方法があります。

DeferredはinitでcreatePublisherというクロージャを受け取り
中でPublisherを生成します。
このクロージャはSubscribeした時に初めて実行されます。

検証

下記のコードをPlaygroundで実行して確認します。

まずFutureの場合


let futurePublisher = Future<String, Never> { promise in
    print("Future 実行")
    promise(.success("hello"))
}

この時点で

Future 実行

が出力されます。

一方Deferredの場合


let deferredPublisher = Deferred { () -> Just<String> in
    print("Deferred 実行")
    return Just("hello")
}

これだけ書いても何も実行されません。

Subscribeしてみると


let cancellable = deferredPublisher
    .sink(receiveCompletion: {
        print("receiveCompletion \($0)")
    }, receiveValue: {
        print("receiveValue \($0)")
    })
Deferred 実行
receiveValue hello
receiveCompletion finished

とSubscribeしてから
クロージャの中が実行されていることがわかります。

これを活用してFutureを遅延実行させる方法が
下記の動画でも紹介されています。


下記の例はFutureの特徴をよく表しているため引用させていただきました。

注意点として下記の例にある2番目の1729という値を受け取ることはありません。

Futureは値を一度受け取るとすぐにCompletionするため
受け取れるのは最初の42だけです。

動画では値を継続的に受け取りたいため
この後Custom Publisherの生成を行っています。


let aFutureInt = Deferred {
  Future<Int, Never> { callback in
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
      print("Hello from inside the future!")
      callback(.success(42))
      callback(.success(1729))
    }
  }
}

※ この時点ではまだSubscribeしていないため
実行はされません。

まとめ

Deferredについて検証してみました。
Deferredを活用することで不必要な処理やセットアップなどが
実行されるリスクを減らすことができます。

またFutureを一緒に活用することで
非同期処理の遅延実行も実現することができることもわかりました。

しかし
Futureは値を一度して受け取らないという特徴を持っているため
使い方を知らないと

「あれっ?なんか思っていたのと違う」

となってしまう可能性もあるので注意が必要ですね😅

何か間違いなどございましたら教えていただけますとうれしいです🙇🏻‍♂️

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
15
Help us understand the problem. What are the problem?