就問(wèn)此時(shí)此刻還有誰(shuí)脐恩?45度仰望天空镐侯,該死!我這無(wú)處安放的魅力驶冒!
- RxSwift(1)—— 初探
- RxSwift(2)—— 核心邏輯源碼分析
- RxSwift(3)—— Observable序列的創(chuàng)建方式
- RxSwift(4)—— 高階函數(shù)(上)
- RxSwift(5)—— 高階函數(shù)(下)
- RxSwift(6)—— scheduler源碼解析(上)
- RxSwift(7)—— scheduler源碼解析(下)
- RxSwift(8)—— KVO底層探索(上)
- RxSwift(9)—— KVO底層探索(下)
- RxSwift(10)—— 場(chǎng)景序列總結(jié)
- RxSwift(11)—— 銷毀者-dispose源碼解析
- RxSwift(12)—— Subject即攻也守
- RxSwift(13)—— 爬過(guò)的坑
- RxSwift(14)—— MVVM雙向綁定
RxSwift目錄直通車--- 和諧學(xué)習(xí)苟翻,不急不躁!
這一篇文章繼續(xù)上一篇:RxSwift-高階函數(shù)(上)給大家介紹
RxSwift
非常重要的高階函數(shù)骗污,也不多說(shuō)崇猫,開(kāi)始介紹
5:從可觀察對(duì)象的錯(cuò)誤通知中恢復(fù)的操作符
5.1:catchErrorJustReturn
- 從錯(cuò)誤事件中恢復(fù),方法是返回一個(gè)可觀察到的序列需忿,該序列發(fā)出單個(gè)元素诅炉,然后終止
print("*****catchErrorJustReturn*****")
let sequenceThatFails = PublishSubject<String>()
sequenceThatFails
.catchErrorJustReturn("Cooci")
.subscribe { print($0) }
.disposed(by: disposeBag)
sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // 正常序列發(fā)送成功的
//發(fā)送失敗的序列,一旦訂閱到位 返回我們之前設(shè)定的錯(cuò)誤的預(yù)案
sequenceThatFails.onError(self.lgError)
5.2:catchError
- 通過(guò)切換到提供的恢復(fù)可觀察序列,從錯(cuò)誤事件中恢復(fù)
print("*****catchError*****")
let recoverySequence = PublishSubject<String>()
sequenceThatFails
.catchError {
print("Error:", $0)
return recoverySequence // 獲取到了錯(cuò)誤序列-我們?cè)谥虚g的閉包操作處理完畢,返回給用戶需要的序列(showAlert)
}
.subscribe { print($0) }
.disposed(by: disposeBag)
sequenceThatFails.onNext("Hank")
sequenceThatFails.onNext("Kody") // 正常序列發(fā)送成功的
sequenceThatFails.onError(lgError) // 發(fā)送失敗的序列
recoverySequence.onNext("CC")
5.3:retry
- 通過(guò)無(wú)限地重新訂閱可觀察序列來(lái)恢復(fù)重復(fù)的錯(cuò)誤事件
print("*****retry*****")
var count = 1 // 外界變量控制流程
let sequenceRetryErrors = Observable<String>.create { observer in
observer.onNext("Hank")
observer.onNext("Kody")
observer.onNext("CC")
if count == 1 {
// 流程進(jìn)來(lái)之后就會(huì)過(guò)度-這里的條件可以作為出口,失敗的次數(shù)
observer.onError(self.lgError) // 接收到了錯(cuò)誤序列,重試序列發(fā)生
print("錯(cuò)誤序列來(lái)了")
count += 1
}
observer.onNext("Lina")
observer.onNext("小雁子")
observer.onNext("婷婷")
observer.onCompleted()
return Disposables.create()
}
sequenceRetryErrors
.retry()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
5.4:retry(_:):
- 通過(guò)重新訂閱可觀察到的序列屋厘,重復(fù)地從錯(cuò)誤事件中恢復(fù)涕烧,直到重試次數(shù)達(dá)到
max
未遂計(jì)數(shù)
print("*****retry(_:)*****")
let sequenceThatErrors = Observable<String>.create { observer in
observer.onNext("Hank")
observer.onNext("Kody")
observer.onNext("CC")
if count < 5 { // 這里設(shè)置的錯(cuò)誤出口是沒(méi)有太多意義的額,因?yàn)槲覀冊(cè)O(shè)置重試次數(shù)
observer.onError(self.lgError)
print("錯(cuò)誤序列來(lái)了")
count += 1
}
observer.onNext("Lina")
observer.onNext("小雁子")
observer.onNext("婷婷")
observer.onCompleted()
return Disposables.create()
}
sequenceThatErrors
.retry(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
6:Rx流程操作符。
6.1:debug
- 打印所有訂閱汗洒、事件和處理澈魄。
print("*****debug*****")
var count = 1
let sequenceThatErrors = Observable<String>.create { observer in
observer.onNext("Hank")
observer.onNext("Kody")
observer.onNext("CC")
if count < 5 {
observer.onError(self.lgError)
print("錯(cuò)誤序列來(lái)了")
count += 1
}
observer.onNext("Lina")
observer.onNext("小雁子")
observer.onNext("可心")
observer.onCompleted()
return Disposables.create()
}
sequenceThatErrors
.retry(3)
.debug()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
6.2: RxSwift.Resources.total:
- 提供所有Rx資源分配的計(jì)數(shù),這對(duì)于在開(kāi)發(fā)期間檢測(cè)泄漏非常有用仲翎。
print("*****RxSwift.Resources.total*****")
print(RxSwift.Resources.total)
let subject = BehaviorSubject(value: "Cooci")
let subscription1 = subject.subscribe(onNext: { print($0) })
print(RxSwift.Resources.total)
let subscription2 = subject.subscribe(onNext: { print($0) })
print(RxSwift.Resources.total)
subscription1.dispose()
print(RxSwift.Resources.total)
subscription2.dispose()
print(RxSwift.Resources.total)
7:鏈接操作符
7.1:multicast
- 將源可觀察序列轉(zhuǎn)換為可連接序列痹扇,并通過(guò)指定的主題廣播其發(fā)射。
func testMulticastConnectOperators(){
print("*****multicast*****")
let subject = PublishSubject<Any>()
subject.subscribe{print("00:\($0)")}
.disposed(by: disposeBag)
let netOB = Observable<Any>.create { (observer) -> Disposable in
sleep(2)// 模擬網(wǎng)絡(luò)延遲
print("我開(kāi)始請(qǐng)求網(wǎng)絡(luò)了")
observer.onNext("請(qǐng)求到的網(wǎng)絡(luò)數(shù)據(jù)")
observer.onNext("請(qǐng)求到的本地")
observer.onCompleted()
return Disposables.create {
print("銷毀回調(diào)了")
}
}.publish()
netOB.subscribe(onNext: { (anything) in
print("訂閱1:",anything)
})
.disposed(by: disposeBag)
// 我們有時(shí)候不止一次網(wǎng)絡(luò)訂閱,因?yàn)橛袝r(shí)候我們的數(shù)據(jù)可能用在不同的額地方
// 所以在訂閱一次 會(huì)出現(xiàn)什么問(wèn)題?
netOB.subscribe(onNext: { (anything) in
print("訂閱2:",anything)
})
.disposed(by: disposeBag)
_ = netOB.connect()
}
- 底層邏輯探索中間變量
ConnectableObservableAdapter
保存了源序列source
溯香、中間序列makeSubject
- 訂閱流程
self.lazySubject.subscribe(observer)
一個(gè)懶加載的序列鲫构,保證了中間變量ConnectableObservableAdapter
每一次都是同一個(gè)響應(yīng)序列 - 剩下就是
PublishSubject
的訂閱效果 - 完事等待源序列的響應(yīng),但是我們的源序列的訂閱是在
connect
函數(shù)里面玫坛!如果沒(méi)有調(diào)用connect
函數(shù)结笨,意味著就永遠(yuǎn)不會(huì)發(fā)送響應(yīng)。這樣背后的邏輯就是湿镀,前面所以的發(fā)送響應(yīng)在connect
函數(shù)之前的都沒(méi)有任何的意義炕吸! - 以上也就說(shuō)明了我們的
publish
就是狀態(tài)共享的:connnect
一次我們序列發(fā)送一次響應(yīng)(響應(yīng)所有訂閱)。
7.2:replay
- 將源可觀察序列轉(zhuǎn)換為可連接的序列勉痴,并將向每個(gè)新訂閱服務(wù)器重放以前排放的緩沖大小
- 首先擁有和
publish
一樣的能力赫模,共享Observable sequence
, 其次使用replay
還需要我們傳入一個(gè)參數(shù)(buffer size)
來(lái)緩存已發(fā)送的事件蒸矛,當(dāng)有新的訂閱者訂閱了瀑罗,會(huì)把緩存的事件發(fā)送給新的訂閱者
func testReplayConnectOperators(){
print("*****replay*****")
let interval = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance).replay(5)
interval.subscribe(onNext: { print(Date.time,"訂閱: 1, 事件: \($0)") })
.disposed(by: self.disposeBag)
delay(2) { _ = interval.connect() }
delay(4) {
interval.subscribe(onNext: { print(Date.time,"訂閱: 2, 事件: \($0)") })
.disposed(by: self.disposeBag)
}
delay(8) {
interval.subscribe(onNext: { print(Date.time,"訂閱: 3, 事件: \($0)") })
.disposed(by: self.disposeBag)
}
delay(20, closure: {
self.disposeBag = DisposeBag()
})
/**
訂閱: 1, 事件: 4
訂閱: 1, 事件: 0
2019-05-28 21-32-42 訂閱: 2, 事件: 0
2019-05-28 21-32-42 訂閱: 1, 事件: 1
2019-05-28 21-32-42 訂閱: 2, 事件: 1
2019-05-28 21-32-45 訂閱: 2, 事件: 4
2019-05-28 21-32-46 訂閱: 3, 事件: 0
2019-05-28 21-32-46 訂閱: 3, 事件: 1
2019-05-28 21-32-46 訂閱: 3, 事件: 2
2019-05-28 21-32-46 訂閱: 3, 事件: 3
2019-05-28 21-32-46 訂閱: 3, 事件: 4
// 序列從 0開(kāi)始
// 定時(shí)器也沒(méi)有斷層 sub2 sub3 和 sub1 是同步的
*/
}
高階函數(shù)的用法還是有點(diǎn)意思的胸嘴!如果你是一個(gè)
RxSwift
新手,還是非常建議大家耐著性子好好練習(xí)斩祭,對(duì)你的開(kāi)發(fā)絕對(duì)有幫助!就問(wèn)此時(shí)此刻還有誰(shuí)劣像?45度仰望天空,該死摧玫!我這無(wú)處安放的魅力耳奕!