為什么使用RxSwift?
我們編寫的代碼絕大多數都涉及對外部事件的響應。當用戶點擊操作時,我們需要編寫一個@IBAction事件來響應。我們需要觀察通知,以檢測鍵盤何時改變位置。當網絡請求響應數據時,我們必須提供閉包來執行。我們使用KVO來檢測變量的變化。所有這些不同的系統使我們的代碼增加了不必要地復雜。如果有一個一致的系統來處理我們的所有的調用/響應代碼,難道不是更好嗎?Rx就是這樣一個系統。
RxSwift是用於大多數主要語言和平台的響應擴展(即Rx)的正式實現。
概念
每一個Observable的實例都是一個序列
Observable序列相比於Swift序列的關鍵優勢點在於它能夠異步地接收元素。這是RxSwift精髓所在,其他的一切都擴展了這個概念。
Observable(ObservableType)等效於SequenceobservableType.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)
致謝
若發現有錯誤的地方,歡迎各位評論,感謝!同時也希望能夠幫助到有需要的同學。
