iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
Mobile Development

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

第 17 天 - Error Handling Operators (上)

  • 分享至 

  • xImage
  •  

嗨,中秋快樂,趁這連假好好洗滌平日的疲憊吧!今天要講Error handling operators

調整API

為了展示Error handling operators,我們把 API 調整一下

  1. 從原本的只return Void跟error,變成return String跟error
  2. 增加了invalid error
  3. 回傳條件隨機產生數字 -10~9,0~9 回傳animals元素,-1~-4回傳invalid錯誤,-10~-5回傳unknown錯誤
class API {

    enum APIError: Error {
        case unknown
        case invalid
    }

    func request() -> Single<String> {
        return Single.create { (single) -> Disposable in

            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

                let animals = ["Dog", "Cat", "Lion", "Tiger", "Koala", "Monkey", "Pig", "Chicken", "Penguin", "Wolf"]

                let number = Int.random(in: -10..<animals.count)

                if number > 0 {
                    single(.success(animals[number]))
                } else if number > -5 {
                    single(.error(APIError.invalid))
                } else {
                    single(.error(APIError.unknown))
                }

            }

            return Disposables.create()
        }
    }

}

接著加入一個按鈕,讓button tap事件去跟subject綁定,這樣點下按鈕就會把 Void 元素傳給 subject了,萬事俱備後我們來看第一個operators。

let subject = PublishSubject<Void>()

button.rx.tap.bind(to: subject).disposed(by: disposeBag)

CatchError

很像Rx版的try catch,定義我們在進行operator時,當catch到.error事件時,要做出怎樣個反應。像以下範例是透過switch了解是哪種錯誤,再把對應的.error轉變成!或是?元素。

let result = subject
    .flatMapLatest { _ in
        API().request().asObservable()
            .catchError {
                let error = $0 as! API.APIError

                switch error {
                    case .unknown:
                        return .just("?")
                    case .invalid:
                        return .just("!")
                }
            }
            .materialize()
    }
    .share()

result.elements().debug("A").subscribe().disposed(by: disposeBag)

result.errors().debug("B").subscribe().disposed(by: disposeBag)

執行結果

A -> Event next(Chicken)
A -> Event next(Lion)
A -> Event next(Pig)
A -> Event next(?)
A -> Event next(Penguin)
A -> Event next(!)

因為在錯誤後有進行catchError將錯誤轉換元素,所以B不會收到.error事件囉!

CatchErrorJustReturn

如果不管什麼錯誤,都直接給個預設值,那就可以選擇catchErrorJustReturn,範例如下

let result = subject
    .flatMapLatest { _ in
        API().request().asObservable()
            .catchErrorJustReturn("!?")
            .materialize()
    }
    .share()

執行結果

A -> Event next(!?)
A -> Event next(Chicken)

今天是快樂連假第一天,所以篇幅稍短(?),明天會繼續Error Handling Operators,明天見


上一篇
第 16 天 - 統整一下Operator的選擇
下一篇
第 18 天 - Error Handling Operators (下)
系列文
RxSwift / 30天探索之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言