RxSwift 系列(一) -- Observables


為什么使用RxSwift?

我們編寫的代碼絕大多數都涉及對外部事件的響應。當用戶點擊操作時,我們需要編寫一個@IBAction事件來響應。我們需要觀察通知,以檢測鍵盤何時改變位置。當網絡請求響應數據時,我們必須提供閉包來執行。我們使用KVO來檢測變量的變化。所有這些不同的系統使我們的代碼增加了不必要地復雜。如果有一個一致的系統來處理我們的所有的調用/響應代碼,難道不是更好嗎?Rx就是這樣一個系統。

RxSwift是用於大多數主要語言和平台的響應擴展(即Rx)的正式實現。

概念

每一個Observable的實例都是一個序列

Observable序列相比於Swift序列的關鍵優勢點在於它能夠異步地接收元素。這是RxSwift精髓所在,其他的一切都擴展了這個概念。

  • Observable(ObservableType)等效於Sequence
  • observableType.subscribe(_:)方法等效於Sequence.makeIterator()
  • ObservableType.subscribe(_:)接收一個觀察者ObserverType參數,它將被訂閱自動接收由可觀察到的序列事件和元素,而不是在返回的生成器上手動調用next()

如果一個Observable發出一個next事件(Event.next(Element)),它還能夠繼續發出更多的事件。但是,如果一個Observable發出一個error事件(Event.error(ErrorType))或者一個completed事件(Event.completed),那么這個Observable序列就不能給訂閱者發送其他的事件了。

Observables and Observers(又名subscribers -- 訂閱者)

除非有訂閱者,否則Observable不會執行它們的閉包。
在下面的例子中,Observable的閉包將不會被執行,因為沒有訂閱者訂閱。

_ = Observable<String>.create({ (observingString) -> Disposable in
        print("the code will not be executed")
        observingString.onNext("😁")
        observingString.onCompleted()
        return Disposables.create()
    })

在下面的例子中,Observable的閉包將會被執行,因為有訂閱者訂閱。

_ = Observable<String>.create({ (observingString) -> Disposable in
        print("the code will be executed")
        observingString.onNext("😁")
        observingString.onCompleted()
        return Disposables.create()
    }).subscribe({ (event) in
        print(event)
    })

我們現在不必擔心上面例子中的Observable是怎樣被創建出來,我會和大家一步一步深入學習。

subscribe(_:)返回一個一次性的實例,該實例表示一個可使用的資源,如訂閱。在前面的簡單示例中,它被忽略了,但是應該正常地處理它。這通常意味着將它添加到一個DisposeBag實例中。

Creating and Subscribing to Observables

有幾種方式創建和訂閱Observables:

  • never
    創建一個永不終止且不發出任何事件的序列。更多詳情

    let disposeBag = DisposeBag()
    Observable<String>.never().subscribe({ (_) in
        print("this will never be printed")
    }).disposed(by: disposeBag)
    
  • empty
    創建一個只發送completed事件的空Observable序列。更多詳情

    let disposeBag = DisposeBag()
    Observable<Int>.empty().subscribe({ (event) in
        print(event)
    }).disposed(by: disposeBag)
    
  • just
    創建一個只有一個元素的Observable序列。更多詳情

    let disposeBag = DisposeBag()
    Observable.just("單一元素").subscribe({ (event) in
        print(event)
    }).disposed(by: disposeBag)
    
  • of
    創建一個固定數量元素的Observable序列。

    let disposeBag = DisposeBag()
    Observable.of("元素1","元素2","元素3","元素4","元素5").subscribe(onNext: { (element) in
        print(element)
    }).disposed(by: disposeBag)
    

    注意:此處用到了subscribe(onNext:)的便利構造方法,有部分參數使用的是默認值。

  • from
    從一個序列(如Array/Dictionary/Set)中創建一個Observable序列。

    let disposeBag = DisposeBag()
    Observable.from(["元素1","元素2","元素3","元素4","元素5"]).subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)
    

    注意:這個例子使用了默認參數$0而不是顯式地命名參數。

  • create
    創建一個自定義的Observable序列。更多詳情

    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({ (element) in
        print(element)
    }).disposed(by: disposeBag)
    
    
  • range
    創建一個Observable序列,它會發出一系列連續的整數,然后終止。更多詳情

    let disposeBag = DisposeBag()
    Observable.range(start: 1, count: 10).subscribe { print($0) }.disposed(by: disposeBag)
    
  • repeatElement
    創建一個Observable序列,它可以無限地釋放給定元素。更多詳情

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

    上述例子中take操作符從一個序列開始返回指定數量的元素。

  • generate
    創建一個Observable序列,只要提供的條件值為true就可以生成值。

    let disposeBag = DisposeBag()
    Observable.generate(initialState: 0, condition: {$0 < 3}, iterate: {$0 + 1}).subscribe(onNext: {print($0)}).disposed(by: disposeBag)
    
  • deferred
    為每一個訂閱者創建一個新的Observable序列。更多詳情

    let disposeBag = DisposeBag()
    var count = 1
    let defferedSequen = Observable<String>.deferred {
        print("count = \(count)")
        count += 1
        
        return Observable.create({ (observer) -> Disposable in
            observer.onNext("山羊")
            observer.onNext("野豬")
            observer.onNext("小貓")
            
            return Disposables.create()
        })
    }
    
    defferedSequen.subscribe(onNext: {print($0)}).disposed(by: disposeBag)
    defferedSequen.subscribe(onNext: {print($0)}).disposed(by: disposeBag)
    
  • error
    創建一個不會發送任何條目並且立即終止錯誤的Observable序列。

    let disposeBag = DisposeBag()
    Observable<Int>.error(TestError.test).subscribe { print($0) }.disposed(by: disposeBag)
    
  • do
    為每個發出的事件調用一個副作用操作,並返回(通過)原始事件。更多詳情

    let disposeBag = DisposeBag()
    Observable.of(["元素1","元素2","元素3"]).do(onNext: {print("next:\($0)")}, onError: {print("error:\($0)")}, onCompleted: { 
        print("completed")
    }).subscribe(onNext: {print($0)}).disposed(by: disposeBag)
    

致謝

若發現有錯誤的地方,歡迎各位評論,感謝!同時也希望能夠幫助到有需要的同學。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM