Why use Rxswift?
Most of the code we write involves responses to external events. When the user clicks on the action, we need to write an @IBAction
event to respond. We need to observe notifications to detect when the keyboard is changing position. When the network requests the response data, we must provide closures to execute. We use it KVO
to detect changes in variables. All of these different systems add unnecessarily complexity to our code. Wouldn't it be better if there was a consistent system to handle all of our call/response codes? Rx
is such a system.
RxSwift
is the formal implementation of the response extension (that is, Rx) for most major languages and platforms.
Concept
Each Observable
instance is a sequence
Observable
Swift
The key advantage of a sequence over a sequence is that it is able to receive elements asynchronously. This is the RxSwift
essence, and everything else expands the concept.
Observable(ObservableType)
is equivalent toSequence
observableType.subscribe(_:)
Method is equivalent toSequence.makeIterator()
ObservableType.subscribe(_:)
Receives an observer ObserverType
parameter that will be subscribed to automatically receive the observable sequence of events and elements instead of manually calling on the returned generatornext()
If an Observable
event is emitted next
( Event.next(Element)
), it can continue to emit more events. However, if an Observable
error
event ( Event.error(ErrorType)
) or an completed
event () is emitted Event.completed
, the Observable
sequence cannot send other events to the Subscriber.
Observables and Observers (aka subscribers-subscribers)
Unless there are subscribers, Observable
their closures are not executed.
In the following example, Observable
the closure will not be executed because there is no subscriber subscription.
_ = Observable<String>.create({ (observingString) -> Disposable in print("the code will not be executed") observingString.onNext("??") observingString.onCompleted() return Disposables.create() })
In the following example, Observable
the closure will be executed because there is a subscriber subscription.
_ = Observable<String>.create({ (observingString) -> Disposable in print("the code will be executed") observingString.onNext("??") observingString.onCompleted() return Disposables.create() }).subscribe({ (event) in print(event) })
We don't have to worry about how the above example Observable
is created, and I'll go into it with you step-by-step.
subscribe(_:)
Returns a one-time instance that represents a resource that can be used, such as a subscription. In the previous simple example, it was ignored, but it should be handled normally. This usually means adding it to an DisposeBag
instance.
Creating and subscribing to Observables
There are several ways to create and subscribe Observables
:
never
Create a sequence that never terminates and does not emit any events. More details
let disposeBag = DisposeBag()Observable<String>.never().subscribe({ (_) in print("this will never be printed")}).disposed(by: disposeBag)
empty
Creates an completed
empty sequence that sends only events Observable
. More details
let disposeBag = DisposeBag()Observable<Int>.empty().subscribe({ (event) in print(event)}).disposed(by: disposeBag)
just
Creates a sequence of only one element Observable
. More details
let disposeBag = DisposeBag()Observable.just("单一元素").subscribe({ (event) in print(event)}).disposed(by: disposeBag)
of
Creates a sequence of a fixed number of elements Observable
.
let disposeBag = DisposeBag()Observable.of("元素1","元素2","元素3","元素4","元素5").subscribe(onNext: { (element) in print(element)}).disposed(by: disposeBag)
Note: the subscribe(onNext:)
Convenient construction method used here has some parameters that use the default values.
from
Array
Dictionary
Set
creates a sequence from a sequence, such as// Observable
.
let disposeBag = DisposeBag()Observable.from(["元素1","元素2","元素3","元素4","元素5"]).subscribe(onNext: { print($0)}).disposed(by: disposeBag)
Note: This example uses default parameters instead $0
of explicitly naming them.
create
Creates a custom Observable
sequence. More details
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
Creates a Observable
sequence that emits a series of consecutive integers and then terminates. More details
let disposeBag = DisposeBag()Observable.range(start: 1, count: 10).subscribe { print($0) }.disposed(by: disposeBag)
repeatElement
Creates a Observable
sequence that can freely release the given element. More details
let disposeBag = DisposeBag()Observable.repeatElement("??").take(3).subscribe(onNext: {print($0)}).disposed(by: disposeBag)
In the example above, the take
operator returns the specified number of elements from the beginning of a sequence.
generate
Creates a Observable
sequence that can generate a value as long as the provided condition value is true.
let disposeBag = DisposeBag()Observable.generate(initialState: 0, condition: {$0 < 3}, iterate: {$0 + 1}).subscribe(onNext: {print($0)}).disposed(by: disposeBag)
deferred
Create a new sequence for each subscriber Observable
. More details
let disposeBag = DisposeBag()var count = 1let 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
Creates a sequence that does not send any entries and immediately terminates the error Observable
.
let disposeBag = DisposeBag()Observable<Int>.error(TestError.test).subscribe { print($0) }.disposed(by: disposeBag)
do
Invokes a side-effect action for each emitted event and returns (passes) the original event. More details
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)
Thanks
If you find the wrong place, you are welcome to comment, thank you! At the same time also hope to help the needy students.
RxSwift Series (i)