iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
Mobile Development

RxSwift / 30天探索之旅系列 第 18

第 18 天 - Error Handling Operators (下)

  • 分享至 

  • xImage
  •  

接續昨天的上集,今天延續上週的範例程式,做以下修改

Retry

如果發生錯誤,想重新嘗試,那就選擇retry,參數需要帶入 maxAttemptCount,值得注意的是,文件中有寫『If you encounter an error and want it to retry once, then you must use retry(2)』,如果要至少 retry 一次的話,是要寫retry(2),而不是retry(1)哦!

let result = subject
    .flatMapLatest { _ in
        API().request().asObservable().debug("Call")
            .retry(3)
            .materialize()
    }
    .share()

執行結果

Call -> Event error(unknown)
Call -> isDisposed
Call -> subscribed
Call -> Event next(Tiger)
A -> Event next(Tiger)
Call -> Event completed
Call -> isDisposed

RetryWhen

如果覺得直接retry不能滿足你的需求,你必須處理更複雜的狀況,也許可以考慮retryWhen,當符合條件下停止retry,或是延遲retry時機,下面程式碼展示延遲retry的範例

let result = subject
    .flatMapLatest { _ in
        API().request().asObservable().debug("Call")
            .retryWhen { error -> Observable<Int> in
                // 1
                let maxAttempt = 3

                // 2
                return error.enumerated().flatMap { attempt, err -> Observable<Int> in
                    //3
                    if attempt >= maxAttempt {
                        return Observable.error(err)
                    }

                    print(" === #\(attempt): Retry after \(attempt*3) seconds ===")
                    // 4, 5
                    return Observable<Int>.timer(.seconds(attempt*3), scheduler: MainScheduler.instance)
                }
            }
            .materialize()
    }
    .share()
  1. 我們建立maxAttempt作為我們最大retry次數
  2. 這裡的errorObservable<Error>enumerated則是會將每個元素變成<index, element>,所以我們使用flatMapObservable<Error>的元素轉成attempt, err,也就是目前是第幾次retry跟目前的error物件。
  3. 當超出我們設定的maxAttempt時,我們就將目前的error物件包成只有一個error事件的Observable,也就是Observable.error(err)
  4. 若還沒超出,我們就回傳一個有timer的 Observable,時間則是設定 attempt*3,藉此來達到 delay 的效果
  5. Observable<Int>.timer(.seconds(attempt*3), scheduler: MainScheduler.instance)表示在n秒後,才會發出第一個元素數字0,然後接著發出.completed結束,若是加了 period,則會在發出第一個元素後,每隔 period 時間發出接下來的元素)

執行結果

2020-09-06 14:35:24.830: Call -> subscribed
2020-09-06 14:35:26.952: Call -> Event error(unknown)
2020-09-06 14:35:26.952: Call -> isDisposed
 === #0: Retry after 0 seconds ===
2020-09-06 14:35:26.952: Call -> subscribed
2020-09-06 14:35:29.128: Call -> Event error(invalid)
2020-09-06 14:35:29.128: Call -> isDisposed
 === #1: Retry after 3 seconds ===
2020-09-06 14:35:32.128: Call -> subscribed
2020-09-06 14:35:34.169: Call -> Event error(unknown)
2020-09-06 14:35:34.169: Call -> isDisposed
 === #2: Retry after 6 seconds ===
2020-09-06 14:35:40.171: Call -> subscribed
2020-09-06 14:35:42.367: Call -> Event error(unknown)
2020-09-06 14:35:42.367: Call -> isDisposed
2020-09-06 14:35:42.367: B -> Event next(unknown)

今天也把下集講完了,明天進入到Schedulers,掰掰!


上一篇
第 17 天 - Error Handling Operators (上)
下一篇
第 19 天 - Schedulers
系列文
RxSwift / 30天探索之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言