简体   繁体   中英

RxSwift purpose of Observable

I am learning about RxSwift and trying to understand the main difference between Observable and PublishSubject aka Sequence.

As far as I understood, Sequences / PublishesSubject act as Observable and Observer. You can subscribe to these and they emit notifications if the value changes. PublishesSubject can be changed.

My question is, what is the purpose of Observables then? I can only create Observable with a fix value with just() or from() . But I can not change these values or append an item, right? So my Observable will only emit the value I assigned to it in the init. Why do I need Observable then, when the actual value is immutable?

Let´s think of a function which returns an Observable<UIImage> . Instead of returning that Observable and then subscribe on next, I can just return an UIImage. Why do I need a Observable?

If I create following Observable:

let observable = Observable.of(1,2,3)

I would have a static Marble diagram.. my Observable will emit 1,2 and 3. And afterwards..? It is ended?

I am just not getting the reason why I should use Observable. Any help is appreciated.

To help you understand, look at Observable.create . You will see that it takes a closure. This closure executes every time an observer subscribes to it.

So if you wanted to implement just using create , you would do something like:

func just(_ value: Int) -> Observable { 
    return Observable.create { observer in 
        observer.onNext(value)
        observer.onCompleted()
        return Disposables.create()
    }
}

Sure, that will just emit the static value very time, but you could do other things...

let random = Observable<Int>.create { observer in
    observer.onNext(Int.random(in: 0..<10))
    observer.onCompleted()
    return Disposables.create()
}

The above will emit a random value and then complete. You could also make a network request in the closure, or you could call onNext every time a button is tapped. RxCocoa has a bunch of them already... So for example:

let result = loginButton.rx.tap
    .withLatestFrom(Observable.combineLatest(usernameTextField.rx.text, passwordTextField.rx.text))
    .map { URLRequest.login(credentials: $0) }
    .flatMapLatest { URLSession.shared.rx.data(request: $0) }
    .subscribe(onNext: { print("data:", $0) }
  • loginButton.rx.tap emits a next event every time the button is tapped.
  • usernameTextField.rx.text & passwordTextField.rx.text emit next events every time the user enters data into one of the text fields.
  • URLSession.shared.rx.data(request:) emits a value when the server responds with data. All of these are (forms of) Observables.

If you really don't like the mutable state of Subjects, you can use normal Observables. This comes in handy when you want to convert your ViewModel to a function instead of a class.

To answer this specific question of yours,

Let´s think of a function which returns an Observable<UIImage>. Instead of returning that Observable and then subscribe on next, I can just return an UIImage. Why do I need a Observable?

Answer is, imagine a situation where you can't immediately return a UIImage . This could be a result of a network operation or, expensive drawing operation that could take time. So it has to be asynchronous. In order to achieve this, you can use Observable<UIImage> instead of UIImage . That way you can immediately return Observable<UIImage> but your subscriber won't receive the UIImage until it's actually finished processing.

Without Observables, you have to pass a block to achieve the same result. This is just one example. There are many use cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM