昨天提到範例中,我們做了一個假的API,他只會回傳.success
,但現實情況下,可能會發生.error
,這時候會怎樣呢?
我們先修改一下我們的API,他會在兩秒後,隨機決定回傳.success
或是.error(APIError.unknown)
。
class API {
enum APIError: Error {
case unknown
}
func request() -> Single<Void> {
.create { (single) -> Disposable in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
if Bool.random() {
single(.success(()))
} else {
single(.error(APIError.unknown))
}
}
return Disposables.create()
}
}
}
測試程式我們修改成,用按鈕去觸發API,接著看看成功或失敗會怎樣
let subject = PublishSubject<Void>()
button.rx.tap.bind(to: subject).disposed(by: disposeBag)
let result = subject.flatMapLatest { API().request() }
result
.debug("A")e
.subscribe()
.disposed(by: disposeBag)
執行結果
57:38.535: A -> subscribed
57:43.164: A -> Event next(())
57:52.817: A -> Event next(())
57:56.016: A -> Event error(unknown)
Unhandled error happened: unknown
57:56.017: A -> isDisposed
前兩次都順利成功,但第三次呼叫API發生.error
了,接著,因為Observable因收到.error
而disposed,後面你再怎麼按鈕他都沒反應,但我們預期是.error
可以做錯誤處理,而不是直接銷毀。
let subject = PublishSubject<Void>()
button.rx.tap.bind(to: subject).disposed(by: disposeBag)
let result = subject.flatMapLatest { API().request().asObservable().materialize() }.share()
result
.debug("A")
.subscribe(onNext: {
if let error = $0.error {
print("B \(error)")
}
if let element = $0.element {
print("C \(element)")
}
})
.disposed(by: disposeBag)
執行結果
27:40.640: A -> subscribed
7:45.073: A -> Event next(error(unknown))
B unknown
27:47.280: A -> Event next(error(unknown))
B unknown
27:51.220: A -> Event next(next(()))
C ()
27:51.220: A -> Event next(completed)
是一個RxSwift的生態系,在這之下有很多RxSwift的專案,今天介紹RxSwiftExt專案下的 materialized+elements.swift ,這是RxSwift的extension,可以把event.element
跟event.error
轉成Observable,有了這extension,我們的程式能再度進化
let subject = PublishSubject<Void>()
button.rx.tap.bind(to: subject).disposed(by: disposeBag)
let result = subject.flatMapLatest { API().request().asObservable().materialize() }.share()
result.elements().debug("C").subscribe().disposed(by: disposeBag)
result.errors().debug("B").subscribe().disposed(by: disposeBag)
執行結果如下
43:40.168: C -> subscribed
43:40.170: B -> subscribed
43:51.042: C -> Event next(())
43:53.832: B -> Event next(unknown)
這樣寫又更加簡潔清晰,轉化成Observable在後續串連也會更方便!
今天補充了Transforming,明天會接著介紹share,就這樣,掰掰