RXSwift 入坑記

以前一直都是命令式編程,這個(gè)view干嘛,那個(gè)label干嘛,這樣的代碼寫(xiě)了幾個(gè)世紀(jì)了,實(shí)在是疲勞了而且重復(fù)使用率很差。其實(shí)我是很早就知道這個(gè)RXSwift了,就是感覺(jué)很復(fù)雜會(huì)拖項(xiàng)目進(jìn)度,一直不敢進(jìn)坑。最近公司不忙,充實(shí)一下自己,為以后的項(xiàng)目鋪好路子,撿起了響應(yīng)式編程。如果哪里不對(duì)的,請(qǐng)各位指正,不懂的也可以評(píng)論,大家一起提高。廢話說(shuō)的太多了,下面開(kāi)始:

為什么要使用

我們編寫(xiě)的絕大部分代碼都涉及到外部事件的響應(yīng)。當(dāng)一個(gè)用戶操作控制的時(shí)候,我們需要寫(xiě)一個(gè)@IBAction來(lái)處理。我們需要觀察通知來(lái)監(jiān)測(cè)鍵盤(pán)如何更改位置。URL回話響應(yīng)數(shù)據(jù)時(shí),我們需要用閉包來(lái)執(zhí)行。我們使用KVO來(lái)監(jiān)聽(tīng)變量的改變。所有這些不同的系統(tǒng)都讓我們的代碼不必要的復(fù)雜。如果有一個(gè)一致統(tǒng)一的系統(tǒng)來(lái)處理這些呼叫/響應(yīng),那豈不是很好。RX就是這樣一個(gè)系統(tǒng)。

概念

所有Observable實(shí)例只是一個(gè)隊(duì)列。

Observable隊(duì)列比swift隊(duì)列的好處就是他可以異步接受元素。這是RXSwift的核心,所有擴(kuò)展都是在這個(gè)概念基礎(chǔ)上的。

  • Observable(ObservableType)Sequence一樣
  • ObservableType.subscribe(_:)Sequence.makeIterator()類似
  • ObservableType.subscribe(_:)擁有一個(gè)觀察者對(duì)象(ObserverType)的參數(shù),這個(gè)對(duì)象將被訂閱自動(dòng)接受隊(duì)列事件和Observable所發(fā)出的元素,而不是手動(dòng)的調(diào)用next()

如果一個(gè)Observable發(fā)出一個(gè)next事件Event.next(Element),她可以繼續(xù)發(fā)出更多的事件。當(dāng)然如果發(fā)出一個(gè)error事件Event.error(ErrorType)或者一個(gè)完成事件Event.completed,Observable隊(duì)列不會(huì)再給訂閱者發(fā)送額外的事件。源代碼里是一個(gè)遞歸枚舉

public enum Event<Element> {

    /// Next element is produced.
    case next(Element)

    /// Sequence terminated with an error.
    case error(Error)

    /// Sequence completed successfully.
    case completed
}

Observables and observers

Observables不會(huì)執(zhí)行訂閱的閉包除非有一個(gè)訂閱者。下面的例子中,Observable的訂閱閉包不會(huì)執(zhí)行,因?yàn)樗](méi)有訂閱者。她只是一個(gè)可被訂閱者。

 _ = Observable<String>.create { observerOfString -> Disposable in
     print("This will never be printed")
     observerOfString.on(.next("??"))
     observerOfString.on(.completed)
     return Disposables.create
  }

下面這種情況,當(dāng)調(diào)用subscribe(_:)方法了,閉包就會(huì)被執(zhí)行了

_ = Observable<String>.create { observerOfString in
         print("Observable created")
         observerOfString.on(.next("??"))
         observerOfString.on(.completed)
         return Disposables.create()
     }
     .subscribe { event in
         print(event)
}

subscribe(_:)這個(gè)方法返回Disposable實(shí)例。這種類型以后會(huì)討論。就是一個(gè)可以被釋放的類型,需要釋放。

構(gòu)建和訂閱Observables

有很多方法來(lái)構(gòu)建和訂閱Observables

never

構(gòu)建一個(gè)從不終止和發(fā)出任何事件的隊(duì)列

let disposeBag = DisposeBag()
let neverSequence = Observable<String>.never()
    
let neverSequenceSubscription = neverSequence
     .subscribe { _ in
          print("This will never be printed")
}
neverSequenceSubscription.disposed(by: disposeBag)

empty

構(gòu)建一個(gè)空的Observable隊(duì)列,只發(fā)出完成事件

let disposeBag = DisposeBag()
 Observable<Int>.empty()
     .subscribe { event in
         print(event)
     }
     .disposed(by: disposeBag)

just

構(gòu)建一個(gè)只有一個(gè)元素的Observable隊(duì)列

let disposeBag = DisposeBag()
Observable.just("??")
   .subscribe { event in
       print(event)
    }
    .disposed(by: disposeBag)

of

構(gòu)建一個(gè)擁有固定數(shù)量元素的Observable序列

let disposeBag = DisposeBag()
    
Observable.of("??", "??", "??", "??")
    .subscribe(onNext: { element in
        print(element)
    })
    .disposed(by: disposeBag)

subscribe(_:)方法接受事件參數(shù),下面這個(gè)例子接受元素參數(shù)

someObservable.subscribe(
    onNext: { print("Element:", $0) },
    onError: { print("Error:", $0) },
    onCompleted: { print("Completed") },
    onDisposed: { print("Disposed") }
)

from

從序列中創(chuàng)建可觀察到的序列,如數(shù)組、字典或集合。

let disposeBag = DisposeBag()
    
Observable.from(["??", "??", "??", "??"])
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

create

構(gòu)建一個(gè)自定義的可觀察序列

 let disposeBag = DisposeBag()
  let myJust = { (element: String) -> Observable<String> in
      return Observable.create { observer in
          observer.on(.next(element))
          observer.on(.completed)
          return Disposables.create()
      }
  }
 myJust("??")
     .subscribe { print($0) }
     .disposed(by: disposeBag)

range

創(chuàng)建一個(gè)可觀察序列,該序列釋放一系列連續(xù)整數(shù),然后終止

let disposeBag = DisposeBag()
 Observable.range(start: 1, count: 10)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

repeatElement

創(chuàng)建一個(gè)可觀察到的序列,它無(wú)限地釋放給定的元素

let disposeBag = DisposeBag()
Observable.repeatElement("??")
     .take(3)
     .subscribe(onNext: { print($0) })
     .disposed(by: disposeBag)

generate

創(chuàng)建一個(gè)可觀察的序列,只要所提供的條件求值為true,就生成值。

let disposeBag = DisposeBag()
 Observable.generate(
        initialState: 0,
        condition: { $0 < 3 },
        iterate: { $0 + 1 }
    )
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

deferred

為每個(gè)訂閱者創(chuàng)建一個(gè)新的可觀察序列。

let disposeBag = DisposeBag()
var count = 1
 let deferredSequence = Observable<String>.deferred {
    print("Creating \(count)")
    count += 1
        
    return Observable.create { observer in
        print("Emitting...")
        observer.onNext("??")
        observer.onNext("??")
        observer.onNext("??")
        return Disposables.create()
    }
}
    
deferredSequence
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
    
deferredSequence
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

error

創(chuàng)建一個(gè)沒(méi)有任何元素的可觀察序列,并立即以錯(cuò)誤結(jié)束。

 let disposeBag = DisposeBag()
 Observable<Int>.error(TestError.test)
    .subscribe { print($0) }
    .disposed(by: disposeBag)

doOn

為每個(gè)發(fā)出的事件調(diào)用副作用動(dòng)作并返回(傳遞)原始事件。

let disposeBag = DisposeBag()
    
Observable.of("??", "??", "??", "??")
    .do(onNext: { print("Intercepted:", $0) }, onError: { print("Intercepted error:", $0) }, onCompleted: { print("Completed")  })
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

限于篇幅,過(guò)長(zhǎng)我自己都懶的會(huì)去看,關(guān)于Subjects的部分在下文詳細(xì)記錄。>>>>>Subjects

最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 最近在學(xué)習(xí)RxSwift相關(guān)的內(nèi)容,在這里記錄一些基本的知識(shí)點(diǎn),以便今后查閱。 Observable 在RxSwi...
    L_Zephyr閱讀 1,895評(píng)論 1 4
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的,對(duì)什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,982評(píng)論 0 10
  • 響應(yīng)式編程簡(jiǎn)介 響應(yīng)式編程是一種基于異步數(shù)據(jù)流概念的編程模式。數(shù)據(jù)流就像一條河:它可以被觀測(cè),被過(guò)濾,被操作,或者...
    說(shuō)碼解字閱讀 3,556評(píng)論 0 5
  • 我從去年開(kāi)始使用 RxJava ,到現(xiàn)在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy閱讀 5,763評(píng)論 7 62
  • 我人生中的第一個(gè)班主任,是個(gè)女人。 是的,就是個(gè)人而已,我甚至都懶得稱呼她一聲老師。 樣貌與年齡都記得不太清了,她...
    黔驢閱讀 409評(píng)論 0 1

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