0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RxSwift で独自のリトライ処理を実現

Last updated at Posted at 2021-10-08

はじめに

エラーが流れてきたときに指定回数、指定条件でリトライする処理は標準オペレータとして提供されており、 retry もしくは retryWhen を利用します。
今回はこのようなエラーが流れてきたときではなく、「nil だったとき」のような独自のリトライトリガーを実現する方法をご紹介します。

方針

  1. flatMap で特定条件時に独自のエラーに変換する
  2. flatMap の中で timer で遅延させて自身を再帰的に呼び出す

ザッとこの2パターンを思いつきました。
1に関しては、リトライ処理のためにエラーを新しく定義するのはどうなのかという点、2はリトライ回数を制御するためにグローバル変数を定義する必要がある点が個人的に感じた悩みポイントです。
実装環境に合わせた判断と工夫を追加で施していただければと思います。

1. エラーに変換してリトライ

enum CustomeError: Error {
    case nilData
}

private func fetch() -> Observable<Data> {
    API.fetch()
        .flatMap { res -> Observable<Data> in
            guard let data = res else {
                return .error(CustomeError.nilData)
            }
            return .just(data)
        }
        .retry(3) // 標準オペレータの利用
}

2. 再帰処理を利用してリトライ

private func fetch() -> Observable<Data> {
    API.fetch()
        .flatMap { res -> Observable<Data> in
            guard let data = res else {
                // 5 秒間隔でリトライ
                return Observable<Int>.timer(.seconds(5), scheduler: MainScheduler.instance)
                    .flatMap { [unowned self] _ in
                        // リトライ回数を制御する場合はここで判定
                        self.fetch() // 再帰
                    }
            }
            return .just(data)
        }
}

おわりに

RxSwift の利用方法メモとして書いてみました。
ご指摘等ございましたら、コメント頂けますと幸いです。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?