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

1:emty

首先來一個空的序列 - 本來序列事件是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)")
}

  • 這種方式不常用,但是我們以點及面展開分析
  • 通過源碼解析查看
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
    observer.on(.completed)
    return Disposables.create()
}

  • 很明顯在訂閱的時候惰匙,直接observer.on(.completed) 發(fā)送了完成信號,非常簡潔
image

2: just

  • 單個信號序列創(chuàng)建
  • 該方法通過傳入一個默認值來初始化署恍,構建一個只有一個元素的Observable隊列,訂閱完信息自動complete呜舒。
  • 下面的樣例锭汛,我們顯示地標注出了Observable的類型為Observable<[String]>,即指定了這個 Observable 所發(fā)出的事件攜帶的數(shù)據(jù)類型必須是String 類型
print("********just********")
//MARK:  just
// 單個信號序列創(chuàng)建
let array = ["FY_Event","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)")
}

  • 感覺有點數(shù)據(jù)便利的感覺
  • 這個序列在平時開發(fā)里面還是應用挺多的袭蝗,看看底層源碼
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ī)訂閱之后就會發(fā)送.next事件
  • 之后就會自動發(fā)送完成事件唤殴,跟我們效果完全吻合
image

3:of

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

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

// 數(shù)組
Observable<[String]>.of(["FY_Event","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

  • 無論字典,數(shù)組朵逝,多個元素都是正常使用
  • 底層源碼的結(jié)構也是中規(guī)中矩
  • 初始化保存調(diào)度環(huán)境和傳入的元素
  • 訂閱流程也是利用sink,然后通過mutableIterator迭代器處理發(fā)送
image

4:from

  • 將可選序列轉(zhuǎn)換為可觀察序列。
  • 從集合中獲取序列:數(shù)組,集合,set 獲取序列 - 有可選項處理 - 更安全
print("********from********")
// MARK:  from
Observable<[String]>.from(optional: ["FY_Event","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

  • self._optional = optional底層初始化可選項保存
  • 訂閱流程判斷是否匹配我們的可選項
  • 發(fā)送observer.on(.next(element))序列
  • 隨即自動observer.on(.completed)完成序列發(fā)送
image

5:deferred

  • 返回一個可觀察序列乡范,該序列在新觀察者訂閱時調(diào)用指定的工廠函數(shù)配名。
  • 這里有一個需求:動態(tài)序列 - 根據(jù)外界的標識 - 動態(tài)輸出
  • 使用deferred()方法延遲Observable序列的初始化,通過傳入的block來實現(xiàn)Observable序列的初始化并且返回晋辆。
print("********defer********")
//MARK:  defer
var isOdd = true
_ = Observable<Int>.deferred { () -> Observable<Int> in
    // 這里設計我們的序列
    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的時候渠脉,把這段工廠閉包執(zhí)行
  • 有種中間層被包裝的感覺
image

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)
}

  • 保存序列中第一個整數(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ī)定的要求
image

7:generate

  • 通過運行產(chǎn)生序列元素的狀態(tài)驅(qū)動循環(huán),使用指定的調(diào)度程序運行循環(huán)厚脉,發(fā)送觀察者消息习寸,從而生成一個可觀察序列。
  • 該方法創(chuàng)建一個只有當提供的所有的判斷條件都為 true 的時候傻工,才會給出動作的 Observable 序列霞溪。
  • 初始值給定 然后判斷條件1判斷條件2 會一直遞歸下去,直到條件1或者條件2不滿足
  • 類似 數(shù)組遍歷循環(huán)
  • -參數(shù)一initialState: 初始狀態(tài)。
  • -參數(shù)二 condition:終止生成的條件(返回“false”時)中捆。
  • -參數(shù)三 iterate:迭代步驟函數(shù)威鹿。
  • -參數(shù)四 調(diào)度器:用來運行生成器循環(huán)的調(diào)度器,默認: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 = ["FY_Event_1","FY_Event_2","FY_Event_3","FY_Event_4","FY_Event_5","FY_Event_6","FY_Event_7","FY_Event_8","FY_Event_9","FY_Event_10"]
Observable.generate(initialState: 0,// 初始值
    condition: { $0 < arr.count}, // 條件1
    iterate: { $0 + 1 })  // 條件2 +2
    .subscribe(onNext: {
        print("遍歷arr:",arr[$0])
    })
    .disposed(by: disposeBag)

image

8:timer

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

// 因為沒有指定期限period,故認定為一次性
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print("111111111 \(event)")
    }
    //.disposed(by: disposeBag)

  • 狀態(tài)碼的不斷攀升,間隔時間不斷發(fā)送響應
image

9:interval

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

image

9:repeatElement

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

image

10:error

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

image

11:never

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

[圖片上傳中...(image-d05944-1591873354261-0)]

12:create()

  • 該方法接受一個 閉包形式的參數(shù)屋讶,任務是對每一個過來的訂閱進行處理冰寻。
  • 下面是一個簡單的樣例。為方便演示皿渗,這里增加了訂閱相關代碼
  • 這也是序列創(chuàng)建的一般方式斩芭,應用非常之多
let observable = Observable<String>.create{observer in
    //對訂閱者發(fā)出了.next事件,且攜帶了一個數(shù)據(jù)"hangge.com"
    observer.onNext("hangge.com")
    //對訂閱者發(fā)出了.completed事件
    observer.onCompleted()
    //因為一個訂閱行為會有一個Disposable類型的返回值乐疆,所以在結(jié)尾一定要returen一個Disposable
    return Disposables.create()
}

//訂閱測試
observable.subscribe {
    print($0)
}

序列的創(chuàng)建也是學習 RxSwift 的根基划乖,有很多時候我遇到很多的BUG,說白了就是根基沒有掌握好!

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挤土,一起剝皮案震驚了整個濱河市琴庵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耕挨,老刑警劉巖细卧,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異筒占,居然都是意外死亡贪庙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門翰苫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來止邮,“玉大人,你說我怎么就攤上這事奏窑〉寂” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵埃唯,是天一觀的道長撩匕。 經(jīng)常有香客問我,道長墨叛,這世上最難降的妖魔是什么止毕? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任模蜡,我火速辦了婚禮,結(jié)果婚禮上扁凛,老公的妹妹穿的比我還像新娘忍疾。我一直安慰自己,他們只是感情好谨朝,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布卤妒。 她就那樣靜靜地躺著,像睡著了一般字币。 火紅的嫁衣襯著肌膚如雪则披。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天纬朝,我揣著相機與錄音收叶,去河邊找鬼。 笑死共苛,一個胖子當著我的面吹牛判没,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隅茎,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼澄峰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辟犀?” 一聲冷哼從身側(cè)響起俏竞,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堂竟,沒想到半個月后魂毁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡出嘹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年席楚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片税稼。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡烦秩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郎仆,到底是詐尸還是另有隱情只祠,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布扰肌,位于F島的核電站抛寝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜墩剖,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一猴凹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岭皂,春花似錦、人聲如沸沼头。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽进倍。三九已至土至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猾昆,已是汗流浹背陶因。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留垂蜗,地道東北人楷扬。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像贴见,于是被迫代替她去往敵國和親烘苹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345