RxSwift(3)—— Observable序列的創(chuàng)建方式

就問此時(shí)此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!


RxSwift目錄直通車--- 和諧學(xué)習(xí),不急不躁!


序列在RxSwift的世界里面是非常重要,平時(shí)開發(fā)過程用好序列的創(chuàng)建,能夠給開發(fā)帶來事半功倍的效果!這個(gè)篇章總結(jié)了常用的序列創(chuàng)建方式

1:emty

首先來一個(gè)空的序列 - 本來序列事件是Int類型的,這里調(diào)用emty函數(shù) 沒有序列,只能complete

print("********emty********")
let emtyOb = Observable<Int>.empty()
_ = emtyOb.subscribe(onNext: { (number) in
    print("訂閱:",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("完成回調(diào)")
}) {
    print("釋放回調(diào)")
}
  • 這種方式不常用,但是我們以點(diǎn)及面展開分析
  • 通過源碼解析查看
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
    observer.on(.completed)
    return Disposables.create()
}
  • 很明顯在訂閱的時(shí)候,直接observer.on(.completed) 發(fā)送了完成信號(hào),非常簡潔

2: just

  • 單個(gè)信號(hào)序列創(chuàng)建
  • 該方法通過傳入一個(gè)默認(rèn)值來初始化,構(gòu)建一個(gè)只有一個(gè)元素的Observable隊(duì)列,訂閱完信息自動(dòng)complete
  • 下面的樣例,我們顯示地標(biāo)注出了Observable的類型為Observable<[String]>,即指定了這個(gè) Observable 所發(fā)出的事件攜帶的數(shù)據(jù)類型必須是String 類型
print("********just********")
//MARK:  just
// 單個(gè)信號(hào)序列創(chuàng)建
let array = ["LG_Cooci","LG_Kody"]
Observable<[String]>.just(array)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

_ = Observable<[String]>.just(array).subscribe(onNext: { (number) in
    print("訂閱:",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("完成回調(diào)")
}) {
    print("釋放回調(diào)")
}
  • 感覺有點(diǎn)數(shù)據(jù)便利的感覺
  • 這個(gè)序列在平時(shí)開發(fā)里面還是應(yīng)用挺多的,看看底層源碼
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
    observer.on(.next(self._element))
    observer.on(.completed)
    return Disposables.create()
}
  • observer.on(.next(self._element))常規(guī)訂閱之后就會(huì)發(fā)送.next事件
  • 之后就會(huì)自動(dòng)發(fā)送完成事件,跟我們效果完全吻合

3:of

  • 此方法創(chuàng)建一個(gè)新的可觀察實(shí)例,該實(shí)例具有可變數(shù)量的元素。
  • 該方法可以接受可變數(shù)量的參數(shù)(必需要是同類型的)
print("********of********")
//MARK:  of
// 多個(gè)元素 - 針對(duì)序列處理
Observable<String>.of("LG_Cooci","LG_Kody")
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 字典
Observable<[String: Any]>.of(["name":"LG_Cooci","age":18])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 數(shù)組
Observable<[String]>.of(["LG_Cooci","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
  • 無論字典,數(shù)組,多個(gè)元素都是正常使用
  • 底層源碼的結(jié)構(gòu)也是中規(guī)中矩
  • 初始化保存調(diào)度環(huán)境和傳入的元素
  • 訂閱流程也是利用sink,然后通過mutableIterator迭代器處理發(fā)送

4:from

  • 將可選序列轉(zhuǎn)換為可觀察序列。
  • 從集合中獲取序列:數(shù)組,集合,set 獲取序列 - 有可選項(xiàng)處理 - 更安全
print("********from********")
// MARK:  from
Observable<[String]>.from(optional: ["LG_Cooci","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
  • self._optional = optional底層初始化可選項(xiàng)保存
  • 訂閱流程判斷是否匹配我們的可選項(xiàng)
  • 發(fā)送observer.on(.next(element))序列
  • 隨即自動(dòng)observer.on(.completed)完成序列發(fā)送

5:deferred

  • 返回一個(gè)可觀察序列,該序列在新觀察者訂閱時(shí)調(diào)用指定的工廠函數(shù)。
  • 這里有一個(gè)需求:動(dòng)態(tài)序列 - 根據(jù)外界的標(biāo)識(shí) - 動(dòng)態(tài)輸出
  • 使用deferred()方法延遲Observable序列的初始化,通過傳入的block來實(shí)現(xiàn)Observable序列的初始化并且返回。
print("********defer********")
//MARK:  defer
var isOdd = true
_ = Observable<Int>.deferred { () -> Observable<Int> in
    // 這里設(shè)計(jì)我們的序列
    isOdd = !isOdd
    if isOdd {
        return Observable.of(1,3,5,7,9)
    }
    return Observable.of(0,2,4,6,8)
    }
    .subscribe { (event) in
        print(event)
    }
  • self._observableFactory = observableFactory初始化保存了這段工廠閉包
func run() -> Disposable {
    do {
        let result = try self._observableFactory()
        return result.subscribe(self)
    }
    catch let e {
        self.forwardOn(.error(e))
        self.dispose()
        return Disposables.create()
    }
}
  • 在訂閱流程到sink的時(shí)候,把這段工廠閉包執(zhí)行
  • 有種中間層被包裝的感覺

6:rang

  • 使用指定的調(diào)度程序生成并發(fā)送觀察者消息,生成指定范圍內(nèi)的可觀察整數(shù)序列。
print("********rang********")
//MARK:  rang
Observable.range(start: 2, count: 5)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 底層源碼
init(start: E, count: E, scheduler: ImmediateSchedulerType) {
    self._start = start
    self._count = count
    self._scheduler = scheduler
}

override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E {
    let sink = RangeSink(parent: self, observer: observer, cancel: cancel)
    let subscription = sink.run()
    return (sink: sink, subscription: subscription)
}
  • 保存序列中第一個(gè)整數(shù)的值。
  • 保存要生成的順序整數(shù)的數(shù)目。
  • 保存調(diào)度環(huán)境
if i < self._parent._count {
    self.forwardOn(.next(self._parent._start + i))
    recurse(i + 1)
}
else {
    self.forwardOn(.completed)
    self.dispose()
}
  • 根據(jù)之前保存的信息,數(shù)據(jù)的狀態(tài)也不斷攀升,然后遞歸到規(guī)定的要求

7:generate

  • 通過運(yùn)行產(chǎn)生序列元素的狀態(tài)驅(qū)動(dòng)循環(huán),使用指定的調(diào)度程序運(yùn)行循環(huán),發(fā)送觀察者消息,從而生成一個(gè)可觀察序列。
  • 該方法創(chuàng)建一個(gè)只有當(dāng)提供的所有的判斷條件都為 true 的時(shí)候,才會(huì)給出動(dòng)作的 Observable 序列。
  • 初始值給定 然后判斷條件1判斷條件2 會(huì)一直遞歸下去,直到條件1或者條件2不滿足
  • 類似 數(shù)組遍歷循環(huán)
  • -參數(shù)一initialState: 初始狀態(tài)。
  • -參數(shù)二 condition:終止生成的條件(返回“false”時(shí))。
  • -參數(shù)三 iterate:迭代步驟函數(shù)。
  • -參數(shù)四 調(diào)度器:用來運(yùn)行生成器循環(huán)的調(diào)度器,默認(rèn):CurrentThreadScheduler.instance。
  • -返回:生成的序列。
print("********generate********")
//MARK:  generate
Observable.generate(initialState: 0,// 初始值
                    condition: { $0 < 10}, // 條件1
                    iterate: { $0 + 2 })  // 條件2 +2
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 數(shù)組遍歷
let arr = ["LG_Cooci_1","LG_Cooci_2","LG_Cooci_3","LG_Cooci_4","LG_Cooci_5","LG_Cooci_6","LG_Cooci_7","LG_Cooci_8","LG_Cooci_9","LG_Cooci_10"]
Observable.generate(initialState: 0,// 初始值
    condition: { $0 < arr.count}, // 條件1
    iterate: { $0 + 1 })  // 條件2 +2
    .subscribe(onNext: {
        print("遍歷arr:",arr[$0])
    })
    .disposed(by: disposeBag)

8:timer

  • 返回一個(gè)可觀察序列,該序列使用指定的調(diào)度程序運(yùn)行計(jì)時(shí)器,在指定的初始相對(duì)到期時(shí)間過后定期生成一個(gè)值。
  • 第一次參數(shù):第一次響應(yīng)距離現(xiàn)在的時(shí)間
  • 第二個(gè)參數(shù):時(shí)間間隔
  • 第三個(gè)參數(shù):線程
print("********timer********")
//MARK:  timer
Observable<Int>.timer(5, period: 2, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
.disposed(by: disposeBag)

// 因?yàn)闆]有指定期限period,故認(rèn)定為一次性
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print("111111111 \(event)")
    }
    //.disposed(by: disposeBag)
  • 狀態(tài)碼的不斷攀升,間隔時(shí)間不斷發(fā)送響應(yīng)

9:interval

  • 返回一個(gè)可觀察序列,該序列在每個(gè)周期之后生成一個(gè)值,使用指定的調(diào)度程序運(yùn)行計(jì)時(shí)器并發(fā)送觀察者消息。
print("********interval********")
//MARK:  interval
// 定時(shí)器
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
    //.disposed(by: disposeBag)

9:repeatElement

  • 使用指定的調(diào)度程序發(fā)送觀察者消息,生成無限重復(fù)給定元素的可觀察序列。
print("********repeatElement********")
//MARK:  repeatElement
Observable<Int>.repeatElement(5)
    .subscribe { (event) in
        // print("訂閱:",event)
    }
    .disposed(by: disposeBag)

10:error

  • 返回一個(gè)以“error”結(jié)束的可觀察序列。
  • 這個(gè)序列平時(shí)在開發(fā)也比較常見,請(qǐng)求網(wǎng)絡(luò)失敗也會(huì)發(fā)送失敗信號(hào)!
print("********error********")
//MARK:  error
// 對(duì)消費(fèi)者發(fā)出一個(gè)錯(cuò)誤信號(hào)
Observable<String>.error(NSError.init(domain: "lgerror", code: 10086, userInfo: ["reason":"unknow"]))
    .subscribe { (event) in
        print("訂閱:",event)
    }
    .disposed(by: disposeBag)

11:never

  • 該方法創(chuàng)建一個(gè)永遠(yuǎn)不會(huì)發(fā)出 Event(也不會(huì)終止)的 Observable 序列。
  • 這種類型的響應(yīng)源 在測(cè)試或者在組合操作符中禁用確切的源非常有用
print("********never********")
//MARK:  never
Observable<String>.never()
    .subscribe { (event) in
        print("走你",event)
    }
    .disposed(by: disposeBag)
print("********never********") 

12:create()

  • 該方法接受一個(gè) 閉包形式的參數(shù),任務(wù)是對(duì)每一個(gè)過來的訂閱進(jìn)行處理。
  • 下面是一個(gè)簡單的樣例。為方便演示,這里增加了訂閱相關(guān)代碼
  • 這也是序列創(chuàng)建的一般方式,應(yīng)用非常之多
let observable = Observable<String>.create{observer in
    //對(duì)訂閱者發(fā)出了.next事件,且攜帶了一個(gè)數(shù)據(jù)"hangge.com"
    observer.onNext("hangge.com")
    //對(duì)訂閱者發(fā)出了.completed事件
    observer.onCompleted()
    //因?yàn)橐粋€(gè)訂閱行為會(huì)有一個(gè)Disposable類型的返回值,所以在結(jié)尾一定要returen一個(gè)Disposable
    return Disposables.create()
}
 
//訂閱測(cè)試
observable.subscribe {
    print($0)
}

序列的創(chuàng)建也是學(xué)習(xí) RxSwift 的根基,有很多時(shí)候我遇到很多的BUG,說白了就是根基沒有掌握好!現(xiàn)在我們的已經(jīng)RxSwift第十節(jié)課上完了,很多同學(xué)對(duì)RxSwift有了一個(gè)比較深入的了解,當(dāng)然這里我還是以博客的形式寫出來,就是希望大家能夠及時(shí)回來看看,我知道,肯定會(huì)有很多同學(xué)回來繼續(xù)加深基礎(chǔ)的!

就問此時(shí)此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容